关于使用套接字API的简单基于TCP的echo服务器

我正在学习套接字网络API。 在这个过程中,我编写了一个使用TCP的简单Echo服务器。 我编写代码的方式是,只要服务器正在运行,客户端控制台上输入的任何内容都应该回显给它。 但是,我无法做到这一点。 虽然,对于第一次输入,我得到了回声,从下次开始,我没有得到任何消息。 我知道,我们可以使用fork()为许多客户端实现它,但是我想知道阻塞客户端的原因,以及可能的方法来纠正它。 以下是客户端的代码:

 #include  #include  #include  #include  #include  #include  #include  #define MAXCOUNT 1024 int main(int argc, char* argv[]) { int sfd; char msg[MAXCOUNT]; char blanmsg[MAXCOUNT]; struct sockaddr_in saddr; memset(&saddr,0,sizeof(saddr)); sfd = socket(AF_INET,SOCK_STREAM,0); saddr.sin_family = AF_INET; inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr); saddr.sin_port = htons(5004); connect(sfd,(struct sockaddr*) &saddr, sizeof(saddr)); for(; ;) { memset(msg,0,MAXCOUNT); memset(blanmsg,0,MAXCOUNT); fgets(msg,MAXCOUNT,stdin); send(sfd,msg,strlen(msg),0); recv(sfd,blanmsg,sizeof(blanmsg),0); printf("%s",blanmsg); fflush(stdout); } exit(0); } 

这是服务器的代码:

 #include  #include  #include  #include  #include  #include  #define MAXCOUNT 1024 int main(int argc, char* argv[]) { int sfd,nsfd,n,i,cn; char buf[MAXCOUNT]; socklen_t caddrlen; struct sockaddr_in caddr,saddr; //Structs for Client and server Address in the Internet sfd = socket(AF_INET,SOCK_STREAM,0); memset(&saddr,0,sizeof(saddr)); //Clear the Server address structure saddr.sin_family = AF_INET; //Internet Address Family saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); saddr.sin_port = htons(5004); bind(sfd, (struct sockaddr*) &saddr,sizeof(saddr)); listen(sfd,1); for(; ;) { caddrlen = sizeof(caddr); nsfd = accept(sfd,(struct sockaddr*) &caddr,&caddrlen); cn = recv(nsfd,buf,sizeof(buf),0); if(cn == 0) { exit(0); } buf[cn] = '\0'; send(nsfd,buf,strlen(buf),0); } close(nsfd); exit(0); } 

您不应该在服务器上的循环内调用accept。 在服务器上的for循环之前移动accept,它应该按照您的预期运行。

在循环中调用accept会使服务器阻塞直到新连接进入。您的客户端只打开一个连接,因此服务器将在第二次调用时阻止接受。

您的代码正是您要求它执行的操作。 您告诉它接受连接,从该连接接收一些数据,将该数据发送回连接,然后接受另一个连接。 这就是它正在做的事情。 我怀疑你想在for循环之外移动accept调用。

 I think you required a code which servers multiple clients as well as echo message to respective clients. so just have a look to your code again and note down modification #include  #include  #include  #include  #include  #include  #define MAXCOUNT 1024 int main(int argc, char* argv[]) { int sfd,nsfd,n,i,cn; char buf[MAXCOUNT]; socklen_t caddrlen; struct sockaddr_in caddr,saddr; //Structs for Client and server Address in the Internet sfd = socket(AF_INET,SOCK_STREAM,0); memset(&saddr,0,sizeof(saddr)); //Clear the Server address structure saddr.sin_family = AF_INET; //Internet Address Family saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); saddr.sin_port = htons(5004); bind(sfd, (struct sockaddr*) &saddr,sizeof(saddr)); listen(sfd,5);/*request queue size*/ while(1) {//main loop for cuncorent server caddrlen = sizeof(caddr); nsfd = accept(sfd,(struct sockaddr*) &caddr,&caddrlen); if(fork()==0) {//only child code for serving a particular client for(; ;) {//loop for reading and writing back msg cotineously cn = recv(nsfd,buf,sizeof(buf),0); if(cn == 0) { exit(0); } buf[cn] = '\0'; send(nsfd,buf,strlen(buf),0); }//serving loop ends close(nsfd); exit(0); }//child code ends }//main while loop ends exit(0); }