Socket网络聊天程序

 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地址的操作麻烦多了,全部都要存放到这个里面。

猜你喜欢

转载自www.cnblogs.com/tangdingkang/p/12073144.html