创建项目
创建空项目,导入素材(可选)。
2. 网络初始化
#include <stdio.h> #include <winsock2.h> #pragma comment (lib, "WS2_32.lib") sockaddr_in sockAddr; // 网络地址 SOCKET serverSocket; // 网络套接字 #define SERVER_IP "118.126.117.125" #define JIAN_KONG_PORT 2022 bool init() { // windows 网络服务的初始化 WSADATA wsaData; int err = WSAStartup(MAKEWORD(1, 1), &wsaData); if (err != 0) { return false; }// 创建套接字 serverSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
// 设置服务器端的网络地址 sockAddr.sin_family = PF_INET; sockAddr.sin_addr.S_un.S_addr = inet_addr(SERVER_IP); sockAddr.sin_port = htons(JIAN_KONG_PORT); return true; }int main(void) { if (!init()) { printf("初始化失败!\n"); return -1; }return 0; }
3. 连接到聊天室服务器
// 连接服务器(发起网络连接) int ret = connect(serverSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr)); if (ret != 0) { printf("连接服务器失败,请检查网络连接!"); return 1; }
4. 登录聊天室
char nickName[16]; //昵称 void GBKToUTF8(string& strGBK) { int len = MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, NULL, 0); wchar_t* wszUtf8 = new wchar_t[len]; memset(wszUtf8, 0, len); MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, wszUtf8, len); len = WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, NULL, 0, NULL, NULL); char* szUtf8 = new char[len + 1]; memset(szUtf8, 0, len + 1); WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, szUtf8, len, NULL, NULL);
strGBK = szUtf8; delete[] szUtf8; delete[] wszUtf8; }void login() { system("mode con lines=5 cols=30"); printf("\n 欢迎使用奇牛 QQ 聊天室\n\n"); printf(" 昵称:"); scanf_s("%s", nickName, sizeof(nickName)); while (getchar() != '\n'); string name = nickName; GBKToUTF8(name); // 转码 send(serverSocket, name.c_str(), strlen(name.c_str()) + 1, 0); }
5. 创建聊天室界面
char line1[111]; char line2[111]; void gotoxy(short x, short y) { COORD pos = { x,y }; HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hOut, pos); }void uiInit() { system("mode con lines=36 cols=110"); system("cls"); gotoxy(0, 33); for (int i = 0; i < 110; i++)line1[i] = '-'; line1[110] = 0; for (int i = 0; i < 110; i++)line2[i] = ' '; line2[110] = 0; printf("%s\n\n", line1); //mciSendString("play res/bg.mp3", 0, 0, 0); }int main(void) {
...... login(); uiInit(); getchar(); return 0; }
6. 创建接收消息的线程
线程的概念
代码实现
int main(void) { if (!init()) { printf("初始化失败!\n"); return -1; }// 连接服务器(发起网络连接) int ret = connect(serverSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr)); if (ret != 0) { printf("连接服务器失败,请检查网络连接!"); return 1; }login(); uiInit(); // 创建接收线程 HANDLE hThread = CreateThread(NULL, 0, ThreadFunRecv, 0, 0, 0); CloseHandle(hThread); //仅关闭线程句柄,对应的线程没有影响 getchar(); return 0; }
线程函数:
DWORD WINAPI ThreadFunRecv(LPVOID param) { char buff[4096];
while (1) { int ret = recv(serverSocket, buff, sizeof(buff), 0); if (ret <= 0) { printf("服务器关闭!\n"); break; }// 打印收到的消息 // to do. }return NULL; }
7. 群聊区的消息打印
多线程的互斥
多线程对共享资源的互斥使用。
共享资源:控制台的光标位置
互斥锁的创建
HANDLE hMutex; //互斥锁(用于线程之间的互斥) bool init() { // windows 网络服务的初始化 WSADATA wsaData; int err = WSAStartup(MAKEWORD(1, 1), &wsaData); if (err != 0) { return false; }// 创建套接字 serverSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // 设置服务器端的网络地址 sockAddr.sin_family = PF_INET; sockAddr.sin_addr.S_un.S_addr = inet_addr(SERVER_IP); sockAddr.sin_port = htons(JIAN_KONG_PORT);
// 创建互斥锁 hMutex = CreateMutex(NULL, FALSE, "console"); //参数 3 表示这个互斥锁的名字 return true; }
使用互斥锁来控制聊天信息的输出
void printMsg(const char* msg) { // 申请互斥锁, INFINITE, 表示如果没有申请到资源就一直等待该资源 WaitForSingleObject(hMutex, INFINITE); // 使用 static 变量表示聊天区域的打印位置 static POINT pos = { 0,0 }; gotoxy(pos.x, pos.y); printf("%s\n", msg); // 获取光标的当前位置(第几行第几列) CONSOLE_SCREEN_BUFFER_INFO bInfo;; HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(hOut, &bInfo); pos.x = bInfo.dwCursorPosition.X; pos.y = bInfo.dwCursorPosition.Y; // 已经到聊天区域的底部 if (pos.y >= 33) { printf("%s\n", line2); // 清除底部的编辑区 printf("\n\n"); // 强迫屏幕向上滚动两行 // 重新绘制分割线 gotoxy(0, 33); printf("%s\n", line1); pos.y -= 1; //调整输出位置 }// 把光标回到编辑区 gotoxy(1, 34); //释放互斥锁 ReleaseMutex(hMutex); }
在接收线程中输出信息
DWORD WINAPI ThreadFunRecv(LPVOID param) { char buff[4096]; while (1) { int ret = recv(serverSocket, buff, sizeof(buff), 0); if (ret <= 0) { printf("服务器关闭!\n"); break; }// 打印收到的消息 printMsg(UTF8ToGBK(buff).c_str()); }return NULL; }
编码转换
std::string UTF8ToGBK(const char* strUTF8) { int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8, -1, NULL, 0); wchar_t* wszGBK = new wchar_t[len + 1]; memset(wszGBK, 0, len * 2 + 2); MultiByteToWideChar(CP_UTF8, 0, strUTF8, -1, wszGBK, len); len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); char* szGBK = new char[len + 1]; memset(szGBK, 0, len + 1); WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL); std::string strTemp(szGBK); if (wszGBK) delete[] wszGBK; if (szGBK) delete[] szGBK; return strTemp; }
8. 在主线程中实现编辑功能
int main(void) { if (!init()) { printf("初始化失败!\n"); return -1; }// 连接服务器(发起网络连接)
int ret = connect(serverSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr)); if (ret != 0) { printf("连接服务器失败,请检查网络连接!"); return 1; }login(); uiInit(); // 创建接收线程 HANDLE hThread = CreateThread(NULL, 0, ThreadFunRecv, 0, 0, 0); CloseHandle(hThread); //仅关闭线程句柄,对应的线程没有影响 while (1) { char buff[1024]; // 存储编辑信息 memset(buff, 0, sizeof(buff)); editPrint(0, '>'); int len = 0; while (1) { if (_kbhit()) { char c = getch(); if (c == '\r') { //使用 getch 读取时,按回车键,返回的是 '\r' break; }editPrint(len + 1, c); buff[len++] = c; } }if (len == 0) { //空行跳过 continue; }// 清除编辑区的当前行 char buff2[1024]; sprintf_s(buff2, sizeof(buff2), "%s\n", line2); editPrint(0, buff2); // 把消息发送到休息区 sprintf_s(buff2, sizeof(buff2), "【localHost@%s】%s", nickName, buff);
printMsg(buff2); // 把消息发送到服务器 send(serverSocket, buff, strlen(buff) + 1, 0); }//getchar(); return 0; }
待完善
实现编辑区的退格删除功能
实现中文输入功能
聊天区多种彩色文本功能
服务器端功能

今天的分享就到这里了,大家要好好学C语言/C++哟~

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!
对于准备学习C/C++编程的小伙伴,如果你想更好的提升你的编程核心能力(内功)不妨从现在开始!
整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)加君羊获取哦~
C语言C++编程学习交流圈子,企鹅君羊:

【点击进入】

C语言从入门到精通(C语言入门C语言教程C语言零基础C语言基础C语言学习C

C语言制作-QQ聊天室相关推荐

  1. C语言实现QQ聊天室小项目 [完整源码]

    聊天小项目用于练习Windows下的 tcp socket编程和线程同步,其中send 和 recv 使用,对tcp数据传输时经常遇到的中文乱码.数据残缺等问题有示范和纠正作用. 项目效果图 客户端代 ...

  2. html制作类似qq聊天室,QQ聊天室主页设计

    下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考.  无标题页 .style2 { font-family: 华文新魏; text-alig ...

  3. 简易QQ聊天室,socket多线程编程(C语言实现),简单易懂

    简易QQ聊天室 实现本功能,仅需了解socket套接字的使用,我已经将socket套接字的监听接受状态封装在了common.c中,相信你看了会有所收获,socket的连接也封装在common.c中. ...

  4. 来,带你实现基于网络通信QQ聊天室-----QQ有这么强!!!

    如何实现基于网络通信的QQ聊天室 目录 认识网络通信 实现QQ聊天室 项目总结 一.认识网络通信 1.前言 作为一名大一的学生,虽然马上就要奔大二啦,但是由于今年下学期学习都是在线上进行的,对课程学习 ...

  5. 安卓android+WebSocket实现简易QQ聊天室

    本篇仅介绍实现聊天室的前端,也就是安卓端代码,后端的实现看链接说明 链接说明 1.后端使用了spring boot 框架,若不熟悉,有关spring boot 入门教程请戳此链接使用Intellij ...

  6. java仿qq群聊_[转载]仿QQ聊天室群聊的练习心得

    javase的学习即将告一段落,作为最后的一个项目练习,仿聊天室的程序编写让我很是头疼了一阵子.说起来还是自己java基础不牢的缘故导致的,虽然整体框架都已经很清晰了但是实际编写过程中却依然磕磕绊绊, ...

  7. java聊天室小程序论文_在Java项目中利用continue与break制作一个聊天室小程序

    在Java项目中利用continue与break制作一个聊天室小程序 发布时间:2020-12-08 16:03:27 来源:亿速云 阅读:98 作者:Leah 在Java项目中利用continue与 ...

  8. C语言实现网络聊天室 socket的简单应用

    C语言实现网络聊天室 socket的简单应用 前言:环境是Linux ,使用了 socket和pthread,主要分为服务器端和客户端两部分,服务器端监听端口发来的请求,收到后向客户端发送一个消息,客 ...

  9. 网络编程-基于MFC的仿QQ聊天室-2020

    基于MFC的仿QQ聊天室(2020) 有幸学习过网络编程的一些知识,出于对编程的热爱,把曾经的一次简单实践编程作业进行了自定义的完成. 编程所需: 编程工具为VS 2010,需要掌握MFC的基本操作以 ...

最新文章

  1. (转)如何从storyBoard中加载其中一个controller
  2. java vector内存结构_Java 数据结构
  3. pythonrequests下载大文件_Python3 使用requests模块显示下载大文件显示进度
  4. 什么是光纤的波长?看看有哪些是你不知道的!
  5. pollard_rho大数分解Java版
  6. 音视频技术开发周刊 | 199
  7. 中国豪华的政府大楼VS破学校
  8. SQL server 2008数据库的备份与还原、分离(转)
  9. 名片管理系统python详解_Python综合应用名片管理系统案例详解
  10. C#中yield用法
  11. 怎样修复电动车电瓶。
  12. 浏览器缓存之Expires Etag Last-Modified max-age详解
  13. 浅析内网即时通讯工具的安全性如何
  14. 【已解决】点击Import Package没有Environment与Effects等问题(从官网下载Environment等相关资源包)
  15. MySQL基础学习_第016章节_简单的查询语句
  16. Linux编译QT项目时报错: error: cannot find -lGL 的解决方法
  17. java魔法师_RxJava魔法师
  18. 逻辑函数的公式化减法
  19. 1命名规则 sentinel_哨兵-1A数据命名规则
  20. 2021年全球与中国重型泥浆泵行业市场规模及发展前景分析

热门文章

  1. 用计算机c语言输出你好,编写第一个C语言程序 - Hello World
  2. 编译原理学习笔记(十九)~习题:将语句翻译为三地址代码
  3. Android adb指令实现应用双开功能
  4. 【java8 stream操作List集合】
  5. 十岁不愁、二十不悔、三十而立、四十不惑、五十知天命、六十耳顺、七十古来稀...
  6. 基于组合权重优化的风格中性多因子选股策略_数量化专题之五十七
  7. 服装制鞋业的特点及管理(转)
  8. Win10 OneNote 一直卡的登录界面
  9. QT小项目------>记事本
  10. 操作系统常见面试题整理