帮我用c++写windows下基于socket通信的聊天室服务器与客户端实现的代码 完成功能: 1.用户注册功能; 2.两个用户服务器发送私密消息; 3.用户创建一个或多个聊天群组; 4.用户加入群组、在群组内发送消息、离开群组; 5.用户之间的聊天信息通过服务器端转发;

时间: 2024-05-13 16:15:06 浏览: 6
以下是基于socket通信的聊天室服务器与客户端的代码,实现了功能:用户注册、私密消息发送、创建聊天群组、加入群组、在群组内发送消息、离开群组、用户之间的聊天信息通过服务器端转发。 服务器端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #pragma comment (lib, "ws2_32.lib") //加载 ws2_32.dll #define BUF_SIZE 100 #define MAX_CLNT 256 void ErrorHandling(char *message); typedef struct { SOCKET socket; struct sockaddr_in addr; char name[20]; } client; typedef struct { int count; client *clnt[MAX_CLNT]; } client_list; client_list clnt_list = {0}; void send_message(char *message, int len, int sender, int receiver); void send_message_all(char *message, int len, int sender); int main(int argc, char *argv[]) { WSADATA wsaData; SOCKET serv_sock, clnt_sock; SOCKADDR_IN serv_addr, clnt_addr; int clnt_addr_size; char message[BUF_SIZE]; int str_len, i; if (argc != 2) { printf("Usage : %s <port>\n", argv[0]); exit(1); } if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { ErrorHandling("WSAStartup() error!"); } serv_sock = socket(PF_INET, SOCK_STREAM, 0); if (serv_sock == INVALID_SOCKET) { ErrorHandling("socket() error!"); } memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(atoi(argv[1])); if (bind(serv_sock, (SOCKADDR*)&serv_addr, sizeof(serv_addr)) == SOCKET_ERROR) { ErrorHandling("bind() error!"); } if (listen(serv_sock, MAX_CLNT) == SOCKET_ERROR) { ErrorHandling("listen() error!"); } while (1) { clnt_addr_size = sizeof(clnt_addr); clnt_sock = accept(serv_sock, (SOCKADDR*)&clnt_addr, &clnt_addr_size); if (clnt_sock == INVALID_SOCKET) { continue; } client *new_client = (client*)malloc(sizeof(client)); new_client->socket = clnt_sock; new_client->addr = clnt_addr; memset(new_client->name, 0, sizeof(new_client->name)); clnt_list.clnt[clnt_list.count++] = new_client; printf("new client connected, count=%d\n", clnt_list.count); send_message_all("[Server] A new client connected.\n", 35, -1); while ((str_len = recv(clnt_sock, message, BUF_SIZE, 0)) != 0) { int index = -1; for (i = 0; i < clnt_list.count; i++) { if (clnt_list.clnt[i]->socket == clnt_sock) { index = i; break; } } if (index == -1) { break; } message[str_len] = '\0'; if (strlen(message) == 0) { continue; } if (message[0] == '/') { char command[BUF_SIZE]; int j = 1; while (j < str_len && message[j] != ' ') { command[j - 1] = message[j]; j++; } command[j - 1] = '\0'; if (strcmp(command, "name") == 0) { char name[BUF_SIZE]; int k = j + 1; while (k < str_len) { name[k - j - 1] = message[k]; k++; } name[k - j - 1] = '\0'; strcpy(clnt_list.clnt[index]->name, name); printf("client %s set name to %s\n", inet_ntoa(clnt_list.clnt[index]->addr.sin_addr), name); send_message_all("[Server] A client set name.\n", 32, -1); } else if (strcmp(command, "to") == 0) { char name[BUF_SIZE]; int k = j + 1; while (k < str_len && message[k] != ' ') { name[k - j - 1] = message[k]; k++; } name[k - j - 1] = '\0'; int receiver = -1; for (i = 0; i < clnt_list.count; i++) { if (strcmp(clnt_list.clnt[i]->name, name) == 0) { receiver = i; break; } } if (receiver == -1) { send_message("[Server] The client does not exist.\n", 38, -1, index); } else { send_message(message, str_len, index, receiver); } } else if (strcmp(command, "create") == 0) { char name[BUF_SIZE]; int k = j + 1; while (k < str_len) { name[k - j - 1] = message[k]; k++; } name[k - j - 1] = '\0'; int flag = 0; for (i = 0; i < clnt_list.count; i++) { if (strcmp(clnt_list.clnt[i]->name, name) == 0) { flag = 1; break; } } if (flag == 1) { send_message("[Server] The group name already exists.\n", 44, -1, index); } else { client *new_client = (client*)malloc(sizeof(client)); new_client->socket = -2; memset(new_client->name, 0, sizeof(new_client->name)); clnt_list.clnt[clnt_list.count++] = new_client; strcpy(clnt_list.clnt[clnt_list.count - 1]->name, name); printf("client %s create group %s\n", inet_ntoa(clnt_list.clnt[index]->addr.sin_addr), name); send_message_all("[Server] A client create group.\n", 34, -1); send_message("[Server] The group created successfully.\n", 44, -1, index); } } else if (strcmp(command, "join") == 0) { char name[BUF_SIZE]; int k = j + 1; while (k < str_len) { name[k - j - 1] = message[k]; k++; } name[k - j - 1] = '\0'; int group = -1; for (i = 0; i < clnt_list.count; i++) { if (strcmp(clnt_list.clnt[i]->name, name) == 0 && clnt_list.clnt[i]->socket == -2) { group = i; break; } } if (group == -1) { send_message("[Server] The group does not exist.\n", 38, -1, index); } else { clnt_list.clnt[index]->socket = -3; send_message("[Server] You have joined the group.\n", 38, -1, index); send_message_all("[Server] A client joined the group.\n", 36, -1); send_message("[Server] You can now send messages in the group.\n", 53, -1, index); } } else if (strcmp(command, "leave") == 0) { if (clnt_list.clnt[index]->socket != -3) { send_message("[Server] You are not in a group.\n", 35, -1, index); } else { clnt_list.clnt[index]->socket = clnt_sock; send_message("[Server] You left the group.\n", 32, -1, index); send_message_all("[Server] A client left the group.\n", 35, -1); } } else if (strcmp(command, "list") == 0) { char list[BUF_SIZE]; memset(list, 0, sizeof(list)); for (i = 0; i < clnt_list.count; i++) { if (clnt_list.clnt[i]->socket == -2) { strcat(list, clnt_list.clnt[i]->name); strcat(list, " "); } } strcat(list, "\n"); send_message(list, strlen(list), -1, index); } else if (strcmp(command, "members") == 0) { if (clnt_list.clnt[index]->socket != -3) { send_message("[Server] You are not in a group.\n", 35, -1, index); } else { char members[BUF_SIZE]; memset(members, 0, sizeof(members)); for (i = 0; i < clnt_list.count; i++) { if (clnt_list.clnt[i]->socket == -3) { strcat(members, clnt_list.clnt[i]->name); strcat(members, " "); } } strcat(members, "\n"); send_message(members, strlen(members), -1, index); } } else { send_message("[Server] Invalid command.\n", 28, -1, index); } } else { if (clnt_list.clnt[index]->socket == -3) { send_message_all(message, str_len, index); } else { send_message_all(message, str_len, index); } } } for (i = 0; i < clnt_list.count; i++) { if (clnt_list.clnt[i]->socket == clnt_sock) { printf("client %s disconnected\n", inet_ntoa(clnt_list.clnt[i]->addr.sin_addr)); send_message_all("[Server] A client disconnected.\n", 36, -1); int j; for (j = i; j < clnt_list.count - 1; j++) { clnt_list.clnt[j] = clnt_list.clnt[j + 1]; } clnt_list.count--; break; } } closesocket(clnt_sock); } closesocket(serv_sock); WSACleanup(); return 0; } void ErrorHandling(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); } void send_message(char *message, int len, int sender, int receiver) { if (receiver < 0 || receiver >= clnt_list.count) { return; } send(clnt_list.clnt[receiver]->socket, message, len, 0); if (sender >= 0 && sender < clnt_list.count) { printf("client %s send message to %s: %s", inet_ntoa(clnt_list.clnt[sender]->addr.sin_addr), inet_ntoa(clnt_list.clnt[receiver]->addr.sin_addr), message); } } void send_message_all(char *message, int len, int sender) { int i; for (i = 0; i < clnt_list.count; i++) { if (sender == i) { continue; } send(clnt_list.clnt[i]->socket, message, len, 0); } if (sender >= 0 && sender < clnt_list.count) { printf("client %s send message to all: %s", inet_ntoa(clnt_list.clnt[sender]->addr.sin_addr), message); } } ``` 客户端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #include <windows.h> #include <conio.h> #pragma comment (lib, "ws2_32.lib") //加载 ws2_32.dll #define BUF_SIZE 100 void ErrorHandling(char *message); void menu(); void register_user(SOCKET hSocket); void set_name(SOCKET hSocket); void send_message(SOCKET hSocket); void send_private_message(SOCKET hSocket); void create_group(SOCKET hSocket); void join_group(SOCKET hSocket); void leave_group(SOCKET hSocket); void list_group(SOCKET hSocket); void list_members(SOCKET hSocket); int main(int argc, char *argv[]) { WSADATA wsaData; SOCKET hSocket; SOCKADDR_IN serv_addr; char message[BUF_SIZE]; int str_len; if (argc != 3) { printf("Usage : %s <IP> <port>\n", argv[0]); exit(1); } if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { ErrorHandling("WSAStartup() error!"); } hSocket = socket(PF_INET, SOCK_STREAM, 0); if (hSocket == INVALID_SOCKET) { ErrorHandling("socket() error!"); } memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(argv[1]); serv_addr.sin_port = htons(atoi(argv[2])); if (connect(hSocket, (SOCKADDR*)&serv_addr, sizeof(serv_addr)) == SOCKET_ERROR) { ErrorHandling("connect() error!"); } menu(); while (1) { char choice = getch(); switch (choice) { case '1': register_user(hSocket); break; case '2': set_name(hSocket); break; case '3': send_message(hSocket); break; case '4': send_private_message(hSocket); break; case '5': create_group(hSocket); break; case '6': join_group(hSocket); break; case '7': leave_group(hSocket); break; case '8': list_group(hSocket); break; case '9': list_members(hSocket); break; case '0': closesocket(hSocket); WSACleanup(); return 0; default: printf("Invalid choice.\n"); break; } menu(); } closesocket(hSocket); WSACleanup(); return 0; } void ErrorHandling(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); } void menu() { system("cls"); printf("=========================================\n"); printf("1. Register\n"); printf("2. Set name\n"); printf("3. Send message to all\n"); printf("4. Send private message\n"); printf("5. Create group\n"); printf("6. Join group\n"); printf("7. Leave group\n"); printf("8. List groups\n"); printf("9. List members\n"); printf("0. Exit\n"); printf("=========================================\n"); } void register_user(SOCKET hSocket) { char message[BUF_SIZE]; printf("Enter username (max 19 characters): "); fgets(message, BUF_SIZE, stdin); message[strlen(message) - 1] = '\0'; send(hSocket, message, strlen(message), 0); recv(hSocket, message, BUF_SIZE, 0); printf("%s\n", message); } void set_name(SOCKET hSocket) { char message[BUF_SIZE]; printf("Enter your name (max 19 characters): "); fgets(message, BUF_SIZE, stdin); message[strlen(message) - 1] = '\0'; sprintf(message, "/name %s", message); send(hSocket, message, strlen(message), 0); } void send_message(SOCKET hSocket) { char message[BUF_SIZE]; printf("Enter message: "); fgets(message, BUF_SIZE, stdin); send(hSocket, message, strlen(message), 0); } void send_private_message(SOCKET hSocket) { char name[20], message[BUF_SIZE]; printf("Enter receiver's name (max 19 characters): "); fgets(name, 20, stdin); name[strlen(name) - 1] = '\0'; printf("Enter message: "); fgets(message, BUF_SIZE, stdin); sprintf(message, "/to %s %s", name, message); send(hSocket, message, strlen(message), 0); } void create_group(SOCKET hSocket) { char name[20], message[BUF_SIZE]; printf("Enter group name (max 19 characters): "); fgets(name, 20, stdin); name[strlen(name) - 1] = '\0'; sprintf(message, "/create %s", name); send(hSocket, message, strlen(message), 0); recv(hSocket, message, BUF_SIZE, 0); printf("%s\n", message); } void join_group(SOCKET hSocket) { char name[20], message[BUF_SIZE]; printf("Enter group name (max 19 characters): "); fgets(name, 20, stdin); name[strlen(name) - 1] = '\0'; sprintf(message, "/join %s", name); send(hSocket, message, strlen(message), 0); recv(hSocket, message, BUF_SIZE, 0); printf("%s\n", message); } void leave_group(SOCKET hSocket) { char message[BUF_SIZE]; sprintf(message, "/leave"); send(hSocket, message, strlen(message), 0); recv(hSocket, message, BUF_SIZE, 0); printf("%s\n

相关推荐

最新推荐

recommend-type

使用c++调用windows打印api进行打印的示例代码

主要介绍了使用c++调用windows打印api进行打印的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
recommend-type

linux系统中c++写日志文件功能分享

主要介绍了linux系统中c++写日志文件功能,简化了glog,只保留了写日志文件的功能,只是改写了linux版本,需要的朋友可以参考下
recommend-type

win10环境下vscode Linux C++开发代码自动提示配置(基于WSL)

主要介绍了win10环境下vscode Linux C++开发代码自动提示配置(基于WSL),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
recommend-type

grpcio-1.63.0-cp38-cp38-linux_armv7l.whl

Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

MATLAB柱状图在信号处理中的应用:可视化信号特征和频谱分析

![matlab画柱状图](https://img-blog.csdnimg.cn/3f32348f1c9c4481a6f5931993732f97.png) # 1. MATLAB柱状图概述** MATLAB柱状图是一种图形化工具,用于可视化数据中不同类别或组的分布情况。它通过绘制垂直条形来表示每个类别或组中的数据值。柱状图在信号处理中广泛用于可视化信号特征和进行频谱分析。 柱状图的优点在于其简单易懂,能够直观地展示数据分布。在信号处理中,柱状图可以帮助工程师识别信号中的模式、趋势和异常情况,从而为信号分析和处理提供有价值的见解。 # 2. 柱状图在信号处理中的应用 柱状图在信号处理
recommend-type

用Spring boot和vue写一个登录注册界面

好的,这是一个比较常见的技术问题,我可以为您提供一些参考资料和思路。首先,您可以使用Spring Boot作为后端框架来处理用户认证和注册的逻辑,比如使用Spring Security实现用户登录认证。同时,您还需要设计相应的数据模型和数据库表结构来存储用户信息。在前端方面,您可以使用Vue.js作为框架来构建登录注册页面,使用Axios来发起API请求并和后端进行交互。当然,在实现过程中,还需要考虑一些具体细节,比如数据校验、安全性和用户体验等方面。希望这些信息能够帮助到您。
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。
recommend-type

"互动学习:行动中的多样性与论文攻读经历"

多样性她- 事实上SCI NCES你的时间表ECOLEDO C Tora SC和NCESPOUR l’Ingén学习互动,互动学习以行动为中心的强化学习学会互动,互动学习,以行动为中心的强化学习计算机科学博士论文于2021年9月28日在Villeneuve d'Asq公开支持马修·瑟林评审团主席法布里斯·勒菲弗尔阿维尼翁大学教授论文指导奥利维尔·皮耶昆谷歌研究教授:智囊团论文联合主任菲利普·普雷教授,大学。里尔/CRISTAL/因里亚报告员奥利维耶·西格德索邦大学报告员卢多维奇·德诺耶教授,Facebook /索邦大学审查员越南圣迈IMT Atlantic高级讲师邀请弗洛里安·斯特鲁布博士,Deepmind对于那些及时看到自己错误的人...3谢谢你首先,我要感谢我的两位博士生导师Olivier和Philippe。奥利维尔,"站在巨人的肩膀上"这句话对你来说完全有意义了。从科学上讲,你知道在这篇论文的(许多)错误中,你是我可以依