2012-02-04 55 views
2

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

#include <stdio.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <string.h> 
#include <unistd.h> 

#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 <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <netinet/in.h> 
#include <sys/types.h> 
#include <sys/socket.h> 

#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); 
}  

回答

6

你不应该调用服务器上的循环中接受的。在服务器上的for循环之前移动accept,它应该如何工作。

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

+1

+1。另外,如果使用fork()进行多次匹配,我会推荐使它成为线程。 – stefan 2012-02-04 03:21:10

1

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

0
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 <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <netinet/in.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#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); 
}  
相关问题