2016-02-19 161 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

你能否从这些来源添加更多细节? –

相关问题