2016-02-19 162 views
0

發送和recv方法工作正常,但當我發送退出recv方法保持循環。我不太瞭解多線程。當我發送'Q'時,連接應該正常關閉,並且必須監聽客戶端。如何使send和recv方法同時工作?

如何同時爲多個客戶端提供服務?

int main() 
{ 
    if (listen(sock, 5) == -1) { 
     cerr<<"unable to listen for clients"<<endl; 
     exit(1); 
    } 

    cout<<"TCPServer Waiting for client on port 8000"<<endl; 
    sin_size = sizeof(struct sockaddr_in); 

    connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size); 
    thread sds(snds),rvs(rcvs); 
    if(sds.joinable()){ 
     sds.join(); 
    } 
    if(rvs.joinable()){ 
     rvs.join(); 
    } 
    close(sock); 
    return 0; 
} 

void rcvs(){ 
    while(1){ 
     bytes_received = recv(connected,recv_data,1024,0); 
     recv_data[bytes_received] = ''; 
     srz_rcv=recv_data; 
     mb.ParseFromString(srz_rcv); 
     srz_rcv=mb.msg(); 
     if (strcmp(srz_rcv.c_str() , "q") == 0 || strcmp(srz_rcv.c_str() , "Q") == 0){ 
      goto FINISH; 
     } 
     else{ 
      cout<<inet_ntoa(client_addr.sin_addr)<<" : "<<srz_rcv<<endl; 
     } 
     mb.Clear(); 
    } 
    FINISH: 
    close(connected); 
    exit(0); 
} 
void snds(){ 
    while(1){ 
     cout<<"sent : "; 
     cin>>send_data; 
     mb.set_msg(send_data); 
     mb.SerializeToString(&srz_snd); 
     if (strcmp(srz_snd.c_str() , "q") == 0 || strcmp(srz_snd.c_str() , "Q") == 0){ 
      send(connected, srz_snd.c_str(),1024, 0); 
      goto FINISH; 
     } 
     else{ 
      send(connected, srz_snd.c_str(),mb.ByteSize(), 0); 
     } 
     mb.Clear(); 
    } 
    FINISH: 
    close(connected); 
    exit(0); 
} 
+0

正確的縮進問題,請修復你的問題。 – Borgleader

+0

發佈**所有**的代碼。例如,什麼是'recv_data'? –

+0

服務器:http://pastebin.com/dMtwiiuP客戶端:http://pastebin.com/yPm3kN25 – jsr

回答

0

當您發送「Q」或「q」時,您似乎正在關閉接受的套接字。如果您在同一進程中同時運行客戶端和服務器時進行測試,則如果您執行close(socket),則阻止recv可能不會返回。請參閱Blocking recv doesn't exit when closing socket from another thread?那裏的答案建議您可以在close之前致電shutdown。另一種方法是將recv更改爲非阻塞,並將其更改爲select,因爲這樣可以更好地控制線程等待的條件。另一方面,如果「Q」或「q」是由運行在不同進程中的客戶端發送的,則只要字符串比較成功,代碼「應該」就會工作。但是,在處理TCP套接字時,建議將它們優雅地關閉。請參閱Properly close a TCP socket在執行close之前,執行shutdown並處理插槽遠端的後續讀取失敗/ fin是建議的方法。

+0

你能否從這些來源添加更多細節? –

相關問題