2012-07-10 77 views
1

enter image description here回聲服務器返回相同的輸入多次

我爲了使回聲服務器(數據I寫入stdout從我的電腦到服務器和移動回我的電腦)寫了下面的代碼。 問題是,雖然回顯顯示在客戶端的終端上,但顯示的次數與其長度相同。

server.cpp

void reflect(int x) 
{ 
int n; 
int m; 
char data[100]; 
cout<<"Entered reflect function"<<endl; 

for(;;) 
{ 
n=read(x,data, 100); 
cout<<"Client sent "<<n<<endl; 

if(n>0) 
{ 
    while(n>0) 
    { 
     m=write(x,data,n); 
     n=n-m; 
    } 
cout<<"Successfully echoed back to client"<<endl; 
} 
}//end of for loop 
} 

int main() 
{ 
sockaddr_in serv; 
bzero(&serv, sizeof(serv)); 
serv.sin_family=AF_INET; 
serv.sin_port=htons(3345); 
inet_aton("127.0.0.1", &(serv.sin_addr)); 

int servfd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
int x; 
x=bind(servfd, (sockaddr*)(&serv), sizeof(serv)); 

cout<<"Bind returned"<<x<<endl; //this displays x as 0 

listen(servfd, 5); 
sockaddr cli; 
int connfd; 
pid_t id=-1; 
socklen_t siz=sizeof(cli); 
for(;;) 
{ 
    if((connfd=accept(servfd, &cli, &siz))>=0) 
     id=fork(); 

    if(id==0) 
     reflect(connfd); 

    else 
     continue; 
} 
} 

client.cpp

int main() 
{ 
int clifd; 
clifd=socket(AF_INET,SOCK_STREAM, IPPROTO_TCP); 
sockaddr_in serv; 
bzero(&serv, sizeof(serv)); 
serv.sin_family=AF_INET; 
serv.sin_port=htons(3345); 
inet_aton("127.0.0.1", &(serv.sin_addr)); 

connect(clifd, (sockaddr*)(&serv), sizeof(serv)); 
int n,m; 
char data[100]; 
char recvd[100]; 
for(;;) 
{ 
    fgets(data, 100,stdin); 
    n=strlen(data); 
    cout<<"You have written "<<n<<endl; 

    if(n>0) 
    { 
     while(n>0) 
     { 
      m=write(clifd,data,n); 
      n=n-m; 
     } 
    } 

    n=read(clifd, recvd, 100); 
    cout<<"Server echoed back "<<n<<endl; 

    if(n>0) 
    { 
     while(n>0) 
     { 
      m=fputs(data,stdout); //gets displayed many times 
      cout<<"m is"<<m<<endl; //gets displayed many times 
      fflush(stdout); 
      n=n-m; 
     } 
     //cout<<data<<endl; 
    } 
} 
} 

問題是什麼?

回答

2

的fputs

返回值 如果成功,則返回一個非負值。 錯誤時,該函數返回EOF。

也許用寫信,而不是得到的字節數寫

0

fputs打印一個C字符串,而不是單個字符,所以你打印整個字符串,每一次在字符的while循環。另外它依賴於你的不是的空字符串。你知道這個長度,所以你可以強制你自己的空終止,或者更好地創建一個std::string開始和長度。

0

此代碼實際上試圖打印數據的次數與數組中的字節數相同。它會返回寫入的字節數,這是4.我不認爲你需要將()和fflush放入循環中。你可以給他們打一次電話。如果你仍然想要while循環,可以檢查返回值(m)並與數據長度(n)比較,如果它們相等,則從循環中斷開。

最後while循環可以通過

fputs(data,stdout); 
fflush(stdout); 

希望更換這會有所幫助。

0

如果新數據到達或未到達,您將處理緩衝區。

,你讀出的數據您可以更改此:

for(;;) 
{ 
    if(fgets(data, 100,stdin)) { /* only process the data, when something arrived. */ 
     n=strlen(data); 
     cout<<"You have written "<<n<<endl; 
     ... 
0

strlen的()函數給出您的輸入不包括終止一個C風格的字符串零字節的字符數。您只能向服務器寫入n個字節(沒有空終止符)。然後,您讀取從服務器回傳的n個字符,並且從不設置recvd緩衝區的其餘部分。所以它會打印內存中的任何垃圾,直到找到零。