0

Send and recv methods working fine but when I send quit the recv method keeps in loop. I don't know much about multi-threading. When I send 'Q' the connection should close properly and it has to listen for clients.

How to make serve for multiple clients simultaneously?

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);
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
jsr
  • 1
  • 4

1 Answers1

0

You seem to be closing the accepted socket when you send a "Q" or "q". If you are testing this while running both the client and server in the same process, a blocking recv might not return if you do a close( socket ). See Blocking recv doesn't exit when closing socket from another thread? The answers there suggest you can call shutdown before close. Another option is to change your recv to non-blocking and block on select instead, since that gives you more control over the conditions of the thread's wait.

On the other hand, if the "Q" or "q" is sent by a client running in a different process, your code "should" work as long as the string comparison succeeds. However, when dealing with TCP sockets, it is always advisable to shut them down gracefully. See Properly close a TCP socket Doing a shutdown and handling the subsequent read failure/fin on the remote end of the socket before doing a close is the suggested method.

Community
  • 1
  • 1
rs557
  • 9
  • 3