IDE:CodeBlocks
(如果在CB下进行Sokcet编程,要添加一个文件)详情请看这个:https://www.cnblogs.com/Xbert/p/5466963.html
然后这个程序是要同时开启客户端和服务端两个,调试很麻烦,建议双开两个codeblocks,链接:https://blog.csdn.net/weixin_41505011/article/details/80575522
客户端代码:
这里开启了一个新线程来接受用户端传来的消息,主线程则可以输出消息
输入quit自动退出了,如果是服务器退出,所有客户端都会退出
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <Winsock2.h> 4 char recvBuf[50]; 5 SOCKET sockSrv; 6 SOCKET sockConn; 7 DWORD WINAPI Server_Receive_Thread(LPVOID lp) 8 { 9 int i; 10 SOCKET s = (SOCKET)lp; 11 while(1){ //之前在这里犯错了,线程也是要循环的,不能用if 12 if(recv(s, recvBuf, 50, 0)>0){ 13 for(i=0;;i++){ 14 if(recvBuf[i]==‘]‘) 15 break; 16 } 17 if(recvBuf[i+2]==‘q‘) 18 if(recvBuf[i+3]==‘u‘) 19 if(recvBuf[i+4]==‘i‘) 20 if(recvBuf[i+5]==‘t‘){ 21 for(int j=0;j<=i;j++) 22 printf("%c",recvBuf[j]); 23 printf("已经退出聊天!\n"); 24 continue; 25 } 26 printf("%s\n", recvBuf); 27 } 28 29 } 30 return 0; 31 } 32 void main() 33 { 34 printf("服务器开启!\n"); 35 WORD wVersionRequested; //要求使用winSock的版本 36 WSADATA wsaData; 37 int err; 38 wVersionRequested = MAKEWORD( 1, 1 ); 39 err = WSAStartup( wVersionRequested, &wsaData ); //初始化winSock 40 if ( err != 0 ) 41 { 42 return; 43 } 44 if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) 45 { 46 WSACleanup( ); //版本不对,即退出 47 return; 48 } 49 SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0); //创建一个套接字, 50 SOCKADDR_IN addrSrv; 51 addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //就是要用来通讯的 IP 地址信息。 52 addrSrv.sin_family=AF_INET; //这是告诉 WinSock 使用的是 IP 地址族 53 addrSrv.sin_port=htons(6000); //sin_port 就是要用来通讯的端口号 54 bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); 55 56 SOCKADDR_IN addrClient; 57 int len=sizeof(SOCKADDR); 58 while(1) 59 { 60 listen(sockSrv,5); 61 //客户端有了连接请求,来用这个函数来接受请求 62 SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); 63 //创建接受消息的线程 64 HANDLE hThread = CreateThread(NULL, 0, Server_Receive_Thread, sockConn, 0, NULL); 65 char sendBuf[50]; 66 sprintf(sendBuf,"您的ip地址是:%s ",inet_ntoa(addrClient.sin_addr)); 67 send(sockConn,sendBuf,strlen(sendBuf)+1,0); 68 char message[50]; 69 while(1){ 70 scanf("%s",message); 71 sprintf(sendBuf,"[Server]:%s ",message); 72 send(sockConn,sendBuf,sizeof(sendBuf),0); 73 if(strcmp(message,"quit")==0) 74 exit(0); 75 } 76 closesocket(sockConn); 77 } 78 }
至于接受的那个“quit”判断,对面输入“quit”就退出了,不想要这个功能删掉就好了。
客户端代码:
1 #include <stdio.h> 2 #include <Winsock2.h> 3 SOCKET sockClient; 4 char recvBuf[50]; 5 // 接收线程的设置是死循环不断得提交recv申请,如果有反馈,就输出。 6 DWORD WINAPI Client_Receive_Thread(LPVOID lp) 7 { 8 SOCKET s = (SOCKET)lp; 9 while(1){ //之前在这里犯错了,线程也是要循环的,不能用if 10 //要用while 11 if(recv(s, recvBuf, 50, 0)>0){ 12 if(recvBuf[0]==‘[‘) 13 if(recvBuf[1]==‘S‘) 14 if(recvBuf[2]==‘e‘) 15 if(recvBuf[3]==‘r‘) 16 if(recvBuf[4]==‘v‘) 17 if(recvBuf[5]==‘e‘) 18 if(recvBuf[6]==‘r‘) 19 if(recvBuf[7]==‘]‘) 20 if(recvBuf[8]==‘:‘) 21 if(recvBuf[9]==‘q‘) 22 if(recvBuf[10]==‘u‘) 23 if(recvBuf[11]==‘i‘) 24 if(recvBuf[12]==‘t‘){ 25 printf("服务器关闭了,程序即将退出\n"); 26 system("pause"); 27 exit(0); 28 } 29 printf("%s\n", recvBuf); 30 } 31 } 32 } 33 void main() 34 { 35 WORD wVersionRequested; 36 WSADATA wsaData; 37 int err; 38 wVersionRequested = MAKEWORD( 1, 1 ); 39 err = WSAStartup( wVersionRequested, &wsaData ); 40 if ( err != 0 ) 41 { 42 return; 43 } 44 if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) 45 { 46 WSACleanup( ); 47 return; 48 } 49 SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0); 50 SOCKADDR_IN addrSrv; 51 addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); 52 addrSrv.sin_family=AF_INET; 53 addrSrv.sin_port=htons(6000); 54 char username[50]; 55 printf("请输出您的姓名:"); 56 scanf("%s",username); 57 int rec = connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); 58 printf("正在连接!请稍后...\n"); 59 if(rec==0){ 60 printf("连接服务器成功!\n"); 61 char welcome[50]; 62 sprintf(welcome,"欢迎用户[%s]加入聊天室!",username); 63 send(sockClient,welcome,sizeof(username),0); 64 }else{ 65 printf("连接失败!"); 66 system("pause"); 67 return; 68 } 69 //创建线程 70 HANDLE hThread = CreateThread(NULL, 0, Client_Receive_Thread, sockClient, 0, NULL); 71 char messages[50]; 72 char SendMessage[50]; 73 //主线程用来发送数据 74 while(1) 75 { 76 scanf("%s",messages); 77 sprintf(SendMessage,"[%s]:%s",username,messages); //将字符串拼接 78 send(sockClient,SendMessage,strlen(SendMessage)+1,0); 79 if(strcmp(messages,"quit")==0) 80 exit(0); 81 } 82 closesocket(sockClient); 83 WSACleanup(); 84 }
至于上面那个不好的看的循环if嵌套。我当时做的时候用strcmp就是返回不了正确的结果。只好这样子写了。
你们要是觉得不好看就去研究一下。
估计看这文章的差不多都是学弟学妹。计算机网络课设并不是很难,源码网上大把的有,本来我不准备把客户端的代码
贴上来的,但想想还是算了。也算还是给我的代码留个纪念吧!
还请你们能思考一下怎么运行的,socket怎么连接的。特别是sockaddr_in这个结构要仔细看一下。后面的题目对于
ip地址的操作麻烦多了,全部都要存放到这个里面。
原文:https://www.cnblogs.com/tangdingkang/p/12073144.html