首页 > 代码库 > 【Chat】实验 -- 实现 C/C++下TCP, 服务器/客户端 "多人聊天室"
【Chat】实验 -- 实现 C/C++下TCP, 服务器/客户端 "多人聊天室"
本次实验利用TCP/IP, 语言环境为 C/C++
利用套接字Socket编程,以及线程处理,
实现Server/CLient 之间多人的聊天系统的基本功能。
结果大致如:
下面贴上代码(参考参考...)
Server 部分:
1 /* TCPdtd.cpp - main, TCPdaytimed */ 2 3 #include <stdlib.h> 4 #include <stdio.h> 5 #include <winsock2.h> 6 #include <time.h> 7 #include "conio.h" 8 #include <windows.h> 9 #include <process.h> 10 #include <math.h> 11 12 #define QLEN 5 13 #define WSVERS MAKEWORD(2, 0) 14 #define BUFLEN 2000 // 缓冲区大小 15 #pragma comment(lib,"ws2_32.lib") //winsock 2.2 library 16 17 SOCKET msock, ssock; /* master & slave sockets */ 18 SOCKET sockets[100] = {NULL}; 19 20 int cc; 21 char *pts; /* pointer to time string */ 22 time_t now; /* current time */ 23 char buf[2000]; /* buffer */ 24 char *input; 25 HANDLE hThread1,hThread[100] = {NULL}; 26 unsigned int threadID,ThreadID[100],number; 27 28 struct sockaddr_in fsin; 29 struct sockaddr_in Sin; 30 31 unsigned int __stdcall Chat(PVOID PM) 32 { 33 char buf1[2000]; 34 char buf2[2000]; 35 char buf3[2000]; 36 char buf4[2000]; 37 (void) time(&now); 38 pts = ctime(&now); 39 sockets[number] = ssock; 40 SOCKET sock = ssock; 41 ThreadID[number] = threadID; 42 unsigned int threadid = threadID; 43 sprintf(buf1," 时间: %s \t【我的线程号: %d 】\n",pts,threadid); 44 (void) send(sock,buf1, sizeof(buf1), 0); 45 sprintf(buf2," 线程号 <%d> 客户<IP:%s 端口:%d> enter \n",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port); 46 printf("%s ",buf2); 47 printf("\t将自动把此数据发送给所有客户! \n"); 48 for(int i=0;i<=number;i++) 49 { 50 if(sockets[i] != NULL && sockets[i] != sock) 51 { 52 (void) send(sockets[i],buf2, sizeof(buf2), 0); 53 printf(" 发送至线程号<%d>成功!\n",ThreadID[i]); 54 } 55 } 56 printf(" \n"); 57 58 59 flag1:cc = recv(sock, buf3, BUFLEN, 0); //cc为接收的字符数 60 if(cc == SOCKET_ERROR|| cc == 0) 61 { 62 (void) time(&now); 63 pts = ctime(&now); 64 sprintf( buf3," 线程号 <%d> 客户<IP:%s 端口:%d> leave ! \n \t\t时间: %s",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port,pts); 65 sock = NULL; 66 sockets[number] = NULL; 67 CloseHandle(hThread[number]); 68 printf("%s ", buf3); 69 printf("\t将自动把此数据发送给所有客户! \n"); 70 for(int i=0;i<=number;i++) 71 { 72 if(sockets[i] != NULL && sockets[i] != sock) 73 { 74 (void) send(sockets[i], buf3, sizeof(buf3), 0); 75 printf(" 发送至线程号<%d>成功!\n",ThreadID[i]); 76 } 77 } 78 printf(" \n"); 79 } 80 81 else if(cc > 0) 82 { 83 (void) time(&now); 84 pts = ctime(&now); 85 sprintf(buf4," 线程号 <%d> 客户<IP:%s 端口:%d>说 :%s \n \t\t时间 : %s",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port,buf3,pts); 86 87 printf("%s ",buf4); 88 printf("\t将自动把此数据发送给所有客户! \n"); 89 for(int i=0;i<=number;i++) 90 { 91 if(sockets[i] != NULL && sockets[i] != sock) 92 { 93 (void) send(sockets[i],buf4, sizeof(buf4), 0); 94 printf(" 发送至线程号<%d>成功!\n",ThreadID[i]); 95 } 96 } 97 printf(" \n"); 98 99 goto flag1;100 }101 (void) closesocket(sock);102 103 return 0;104 }105 106 107 /*------------------------------------------------------------------------108 * main - Iterative TCP server for DAYTIME service109 *------------------------------------------------------------------------110 */111 void main(int argc, char *argv[]) 112 /* argc: 命令行参数个数, 例如:C:\> TCPdaytimed 8080 113 argc=2 argv[0]="TCPdaytimed",argv[1]="8080" */114 {115 int alen; /* from-address length */ 116 WSADATA wsadata; 117 char *service = "5050"; 118 WSAStartup(WSVERS, &wsadata); //加载 winsock 2.2 library119 msock = socket(PF_INET, SOCK_STREAM, 0); //生成套接字。TCP协议号=6, UDP协议号=17120 memset(&Sin, 0, sizeof(Sin));121 Sin.sin_family = AF_INET;122 Sin.sin_addr.s_addr = INADDR_ANY; //指定绑定接口的IP地址。INADDR_ANY表示绑定(监听)所有的接口。123 Sin.sin_port = htons((u_short)atoi(service)); //atoi--把ascii转化为int,htons - 主机序(host)转化为网络序(network), s(short) 124 bind(msock, (struct sockaddr *)&Sin, sizeof(Sin)); // 绑定端口号(和IP地址)125 listen(msock, 5); //队列长度为5126 127 printf("\t\t\t\t Chat 多人聊天程序 \n");128 printf("\t\t\t\t (Server) \n");129 (void) time(&now);130 pts = ctime(&now);131 printf("\t\t\t 时间 :%s",pts);132 number = -1;133 while(1) //检测是否有按键134 { 135 alen = sizeof(struct sockaddr);136 ssock = accept(msock, (struct sockaddr *)&fsin, &alen);137 number ++;138 hThread[number] = (HANDLE)_beginthreadex(NULL, 0,Chat,NULL, 0, &threadID); 139 }140 (void) closesocket(msock);141 WSACleanup(); //卸载载 winsock 2.2 library142 }
Client 部分:
1 /* TCPClient.cpp -- 用于传递struct */ 2 #include <stdlib.h> 3 #include <stdio.h> 4 #include <winsock2.h> 5 #include <string.h> 6 #include <time.h> 7 #include <windows.h> 8 #include <process.h> 9 #include <math.h> 10 11 #define BUFLEN 2000 // 缓冲区大小 12 #define WSVERS MAKEWORD(2, 0) // 指明版本2.0 13 #pragma comment(lib,"ws2_32.lib") // 指明winsock 2.0 Llibrary 14 15 /*------------------------------------------------------------------------ 16 * main - TCP client for DAYTIME service 17 *------------------------------------------------------------------------ 18 */ 19 20 SOCKET sock,sockets[100] = {NULL}; /* socket descriptor */ 21 // int cc; /* recv character count */ 22 char *packet = NULL; /* buffer for one line of text */ 23 char *pts,*input; 24 HANDLE hThread; 25 unsigned threadID; 26 27 unsigned int __stdcall Chat(PVOID PM ) 28 { 29 time_t now; 30 (void) time(&now); 31 pts = ctime(&now); 32 char buf[2000]; 33 34 while(1) 35 { 36 int cc = recv(sock, buf, BUFLEN, 0); //cc为接收的字符数 37 if(cc == SOCKET_ERROR|| cc == 0) 38 { 39 printf("Error: %d.----",GetLastError()); 40 printf("与服务器断开连接!\n"); 41 CloseHandle(hThread); 42 (void)closesocket(sock); 43 break; 44 } 45 else if(cc > 0) 46 { 47 // buf[cc] = ‘\0‘; 48 printf("%s\n",buf); 49 // printf("输入数据(exit退出): \n"); 50 } 51 } 52 return 0; 53 } 54 55 int main(int argc, char *argv[]) 56 { 57 time_t now; 58 (void) time(&now); 59 pts = ctime(&now); 60 char *host = "127.0.0.1"; /* server IP to connect */ 61 // char *host = "172.18.33.155"; 62 // char *host = "172.18.33.93"; 63 // char *host = "172.18.187.1"; 64 char *service = "5050"; /* server port to connect */ 65 // char *service = "50000"; 66 struct sockaddr_in sin; /* an Internet endpoint address */ 67 WSADATA wsadata; 68 WSAStartup(WSVERS, &wsadata); /* 启动某版本Socket的DLL */ 69 70 memset(&sin, 0, sizeof(sin)); 71 sin.sin_family = AF_INET; 72 sin.sin_port = htons((u_short)atoi(service)); //atoi:把ascii转化为int. htons:主机序(host)转化为网络序(network), s--short 73 sin.sin_addr.s_addr = inet_addr(host); //如果host为域名,需要先用函数gethostbyname把域名转化为IP地址 74 75 sock = socket(PF_INET, SOCK_STREAM,0); 76 77 connect(sock, (struct sockaddr *)&sin, sizeof(sin)); 78 79 printf("\t\t\t\tChat 多人聊天程序 \n"); 80 printf("\t\t\t\t (Client) \n"); 81 hThread = (HANDLE)_beginthreadex(NULL, 0,Chat, NULL, 0, &threadID); 82 printf(" \t\t\t\t 【您可以自由发言】\n\n"); 83 while(1) 84 { 85 char buf1[2000]; 86 87 // scanf("%s",&buf1); 88 89 gets_s(buf1); 90 if(!strcmp(buf1 ,"exit")) 91 goto end; 92 93 (void) send(sock,buf1, sizeof(buf1), 0); 94 (void) time(&now); 95 pts = ctime(&now); 96 printf(" 发送成功! ------时间: %s\n",pts); 97 } 98 99 end: CloseHandle(hThread);100 closesocket(sock);101 WSACleanup(); /* 卸载某版本的DLL */ 102 103 printf("按回车键继续...");104 getchar();105 return 0; /* exit */106 }
【Chat】实验 -- 实现 C/C++下TCP, 服务器/客户端 "多人聊天室"
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。