当前位置:网站首页>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++编程学习交流圈子,企鹅君羊:
边栏推荐
猜你喜欢
每月稳定干2万
TRACE32——Break
环网冗余式CAN/光纤转换器 CAN总线转光纤转换器中继集线器hub光端机
DeFi 前景展望:概览主流 DeFi 协议二季度进展
线程池的使用(结合Future/Callable使用)
TRACE32——List源代码查看
400 times performance improvement 丨 swap valuation optimization case calculation
Shiny04---DT和进度条在shiny中的应用
It turns out that Maya Arnold can also render high-quality works!Awesome Tips
cmake 学习使用笔记(三)
随机推荐
《基于R语言的自动数据收集》--第3章 XML和JSON
Summary of Text Characterization Methods
C-Eighty seven(背包+bitset)
UDP broadcast
导出SQLServer数据到Excel中
七夕?编程?
【LeetCode】235.二叉搜索树的最近公共祖先
二叉搜索树问题
MobileNetV1架构解析
工作3年,回想刚入门和现在的今昔对比,笑谈一下自己的测试生涯
Put Cloudflare on the website (take Tencent Cloud as an example)
强网杯2022 pwn 赛题解析——house_of_cat
Vulnhub靶机:HA_ NARAK
Mysql master-slave delay reasons and solutions
Redis数据库学习
In the anaconda Promat interface, import torch is passed, and the error is reported in the jupyter notebook (only provide ideas and understanding!)
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
对数据类型而言运算符无效。运算符为 add,类型为 text。
Week 8 Document Clustering
Re regular expressions