当前位置:网站首页>C语言制作-QQ聊天室
C语言制作-QQ聊天室
2022-08-05 07:16:00 【cpp编程】
#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; }// 连接服务器(发起网络连接) int ret = connect(serverSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr)); if (ret != 0) { printf("连接服务器失败,请检查网络连接!"); return 1; }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); }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; }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; }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; }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), "【[email protected]%s】%s", nickName, buff);
printMsg(buff2); // 把消息发送到服务器 send(serverSocket, buff, strlen(buff) + 1, 0); }//getchar(); return 0; }今天的分享就到这里了,大家要好好学C语言/C++哟~
欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!
对于准备学习C/C++编程的小伙伴,如果你想更好的提升你的编程核心能力(内功)不妨从现在开始!
整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)加君羊获取哦~
C语言C++编程学习交流圈子,企鹅君羊:
边栏推荐
- 2022.8.2 模拟赛
- AI+视频技术助力保障校园安全,校园智能安防平台该如何建设?
- TRACE32——Break
- Summary of Text Characterization Methods
- Use of thread pool (combined with Future/Callable)
- PCI Pharma Services Announces Multi-Million Dollar Expansion of UK Manufacturing Facility to Meet Growing Demand for Global High Potency Drug Manufacturing Services to Support Oncology Treatment
- 行业应用软件项目经理三步曲
- 导出SQLServer数据到Excel中
- protobuf根据有关联的.proto文件进行编译
- 每月稳定干2万
猜你喜欢
随机推荐
唤醒手腕 - 微信小程序、QQ小程序、抖音小程序学习笔记(更新中)
每一个女孩曾经都是一个没有泪的天使
Tencent Business Security Post IDP Talk Summary
TRACE32——外设寄存器查看与修改
本地能ping通虚拟机,虚拟机ping不通本地
In the anaconda Promat interface, import torch is passed, and the error is reported in the jupyter notebook (only provide ideas and understanding!)
Vulnhub靶机:HA_ NARAK
Mysql master-slave delay reasons and solutions
RNote108---Display the running progress of the R program
Flink Learning 10: Use idea to write WordCount and package and run
微信 小程序 之PC端 不支持 wx.previewMedia 方法 故用自定义轮播图进行 模拟照片视频的播放
【LeetCode】235.二叉搜索树的最近公共祖先
栈与队列的基本介绍和创建、销毁、出入、计算元素数量、查看元素等功能的c语言实现,以及栈的压入、弹出序列判断,栈结构的链式表示与实现
不能比较或排序 text、ntext 和 image 数据类型
MongoDB 语法大全
MySQL: JDBC programming
Takeda Fiscal 2022 First Quarter Results Strong; On Track to Achieve Full-Year Management Guidance
国家强制性灯具安全标准GB7000.1-2015
标准C语言15
算法拾遗十五补链表相关面试题









