3
      Socket A(local_address);

     void enviar(sockaddr_in remote_address, std::atomic<bool>& quit){
        std::string message_text;
        Message message;
        while(!quit){
           std::getline(std::cin, message_text);
           if (message_text != "/quit"){
               memset(message.text, 0, 1024);
               message_text.copy(message.text, sizeof(message.text) - 1, 0);
               A.send_to(message, remote_address);
           }
           else { 
               quit = true; 
           }
        } 
    }

    void recibir(sockaddr_in local_address, std::atomic<bool>& quit){
        Message messager;
        while(!quit){
            A.receive_from(messager, local_address);
        }
    }

    int main(void){
        std::atomic<bool> quit(false);
        sockaddr_in remote_address = make_ip_address("127.0.0.1",6000);

        std::thread hilorec(&recibir,local_address, std::ref(quit));
        std::thread hiloenv(&enviar,remote_address, std::ref(quit));

        hiloenv.join();
        hilorec.join();
    }

Hi! I'm trying to make a simple chat with sockets. I want the program to finish when I write "/quit". I'm trying this with an atomic bool variable called quit. The problem is when I write "/quit" quit will be 'true' and the hiloenv thread will be finish, but hilorec, which is to receive the messages, will be blocked until i receive a message because of the recvfrom() function. How i can solve this?

Sorry for my english and thanks!

Cristian
  • 61
  • 2

4 Answers4

3

Shutdown the socket for input. That will cause recvfrom() to return zero as though the peer had closed the connection, which will cause that thread to exit.

user207421
  • 305,947
  • 44
  • 307
  • 483
1

I would send some special (e.g. empty) message to A socket from main thread when quit is detected. In this case your while(!quit) ... loop will finish and so the thread.

c-smile
  • 26,734
  • 7
  • 59
  • 86
0

If you want to create a single thread app, then use epoll or select apis. If you want to stick to your current design, then you can create your socket having timeout set. Please look for How to set socket timeout in C when making multiple connections? for details. SO when you do quit, the waiting thread will come out of recv or send after the timout and then thread will join and your application can quit gracefully.

Community
  • 1
  • 1
Ritesh
  • 1,809
  • 1
  • 14
  • 16
0

Thanks for the answers. I managed to fix it, If anyone is interested how:

     std::thread hilorec(&recibir,local_address);
     std::thread hiloenv(&enviar,remote_address);

     while(!quit){}

     pthread_cancel(hilorec.native_handle());
     pthread_cancel(hiloenv.native_handle());

     hilorec.join();
     hiloenv.join(); 
Cristian
  • 61
  • 2