2012-02-04 54 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); 
}  
相關問題