前面的程序,不管服务器端还是客户端,都有一个问题,就是处理完一个请求立即退出了,没有太大的实际意义。能不能像Web服务器那样一直接受客户端的请求呢?能,使用while循环即可。
修改前面的回声程序,使服务器端可以不断响应客户端的请求。
服务器端server.cpp:
#include#include#pragmacomment(lib,"ws2_32.lib")//加载ws2_32.dll#defineBUF_SIZE100intmain(){WSADATAwsaData;WSAStartup(MAKEWORD(2,2),&wsaData);//创建套接字SOCKETservSock=socket(AF_INET,SOCK_STREAM,0);//绑定套接字sockaddr_insockAddr;memset(&sockAddr,0,sizeof(sockAddr));//每个字节都用0填充sockAddr.sin_family=PF_INET;//使用IPv4地址sockAddr.sin_addr.s_addr=inet_addr("127.0.0.1");//具体的IP地址sockAddr.sin_port=htons(1234);//端口bind(servSock,(SOCKADDR*)&sockAddr,sizeof(SOCKADDR));//进入监听状态listen(servSock,20);//接收客户端请求SOCKADDRclntAddr;intnSize=sizeof(SOCKADDR);charbuffer[BUF_SIZE]={0};//缓冲区while(1){SOCKETclntSock=accept(servSock,(SOCKADDR*)&clntAddr,&nSize);intstrLen=recv(clntSock,buffer,BUF_SIZE,0);//接收客户端发来的数据send(clntSock,buffer,strLen,0);//将数据原样返回closesocket(clntSock);//关闭套接字memset(buffer,0,BUF_SIZE);//重置缓冲区}//关闭套接字closesocket(servSock);//终止DLL的使用WSACleanup();return0;}
客户端client.cpp:
#include#include#include#pragmacomment(lib,"ws2_32.lib")//加载ws2_32.dll#defineBUF_SIZE100intmain(){//初始化DLLWSADATAwsaData;WSAStartup(MAKEWORD(2,2),&wsaData);//向服务器发起请求sockaddr_insockAddr;memset(&sockAddr,0,sizeof(sockAddr));//每个字节都用0填充sockAddr.sin_family=PF_INET;sockAddr.sin_addr.s_addr=inet_addr("127.0.0.1");sockAddr.sin_port=htons(1234);charbufSend[BUF_SIZE]={0};charbufRecv[BUF_SIZE]={0};while(1){//创建套接字SOCKETsock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);connect(sock,(SOCKADDR*)&sockAddr,sizeof(SOCKADDR));//获取用户输入的字符串并发送给服务器printf("Inputastring:");gets(bufSend);send(sock,bufSend,strlen(bufSend),0);//接收服务器传回的数据recv(sock,bufRecv,BUF_SIZE,0);//输出接收到的数据printf("Messageformserver:%sn",bufRecv);memset(bufSend,0,BUF_SIZE);//重置缓冲区memset(bufRecv,0,BUF_SIZE);//重置缓冲区closesocket(sock);//关闭套接字}WSACleanup();//终止使用DLLreturn0;}
先运行服务器端,再运行客户端,结果如下:
Inputastring:clanguage
Messageformserver:clanguage
Inputastring:C语言中文网
Messageformserver:C语言中文网
Inputastring:学习C/C++编程的好网站
Messageformserver:学习C/C++编程的好网站
while(1)让代码进入死循环,除非用户关闭程序,否则服务器端会一直监听客户端的请求。客户端也是一样,会不断向服务器发起连接。
需要注意的是:server.cpp中调用closesocket()不仅会关闭服务器端的socket,还会通知客户端连接已断开,客户端也会清理socket相关资源,所以client.cpp中需要将socket()放在while循环内部,因为每次请求完毕都会清理socket,下次发起请求时需要重新创建。后续我们会进行详细讲解。