0

Hi i am learning sockets in c, and so far everything was working fine until i tried to close connection in my client and try to reconnect after, the problem is that the server stays stuck on recv() method after the client closes the socket refering to the connection. The question is how can i close the connection in my client and detect it on server side so i could accept a new connection after and the process does not get hang. I have also tried to catch sigpipe but i read some posts and they said that sigpipe was only generated on write() method is that true? Here is my code in case it helps understanding my problem, Thanks a lot.

int network_main_loop(int listening_socket){
    signal(SIGINT, sigHandler);
    signal(SIGSEGV, sigHandler);
    signal(SIGTSTP, sigHandler);
    signal(SIGABRT, sigHandler);
    //sigaction(SIGPIPE, &(struct sigaction){pipeHandler}, NULL);
    //signal(SIGPIPE, SIG_IGN);
    int connsockfd;
    struct sockaddr_in client;
    socklen_t size_client;

    while ((connsockfd = accept(listening_socket, (struct sockaddr *)&client, &size_client)) >= 0)
    {
        int quit = 0;
        char clientADDR[100];
        printf("\nConnected To a Client - %s:%d!\n", inet_ntop(AF_INET, &client.sin_addr, clientADDR, sizeof(clientADDR)), htons(client.sin_port));
        while (quit == 0)
        {
            MessageT *clientRequest = network_receive(connsockfd);
            if (clientRequest != NULL)
            {
                int status = invoke(clientRequest);
                printf("Status:%d\n", status);
                if (status == -1)
                {

                    clientRequest->data_size = 0;
                    clientRequest->opcode = MESSAGE_T__OPCODE__OP_ERROR;
                    clientRequest->c_type = MESSAGE_T__C_TYPE__CT_NONE;
                    clientRequest->data_size = -1;
                    printf("ERROR!");

                    if (network_send(connsockfd, clientRequest) == -1)
                        quit = 1;
                }
                else
                {

                    if (network_send(connsockfd, clientRequest) == -1)
                        quit = 1;
                }
            }
            else
                quit = 1;
        }
        printf("\nConnected To %s:%d is Closed!\n", inet_ntop(AF_INET, &client.sin_addr, clientADDR, sizeof(clientADDR)), htons(client.sin_port));
        close(connsockfd);
    }
    return 0;
}
Bruno Cotrim
  • 57
  • 1
  • 6
  • 3
    Where is your `recv()` call? It returns `0` at EOF, are you checking for that? – Barmar Oct 28 '21 at 17:34
  • First things first i would like to thank you guys for the help, @Barmar i did not know that `recv()` could also return 0 in case of an error i thought it could only receive -1, i made a function that tries to guarantee that i receive the n bytes that i expect and i used -1 for error. – Bruno Cotrim Oct 28 '21 at 17:49
  • It's not an error. That's how EOF is indicated. – Barmar Oct 28 '21 at 17:49
  • @Barmar So how does recv() differentiates the act of waiting for data and receiving no data, internally? – Bruno Cotrim Oct 28 '21 at 17:52
  • 1
    If you're in blocking mode, it doesn't return until there's data or EOF. If you're in non-blocking mode, no data available is reported as an error with `errno = EWOULDBLOCK` – Barmar Oct 28 '21 at 19:40
  • @Barmar "*If you're in blocking mode, it doesn't return until there's data or EOF **or error**. If you're in non-blocking mode, no data available is reported as an error with `errno = EWOULDBLOCK` **or `EAGAIN`**, [depending on platform](https://stackoverflow.com/questions/49049430/)*" – Remy Lebeau Oct 28 '21 at 20:13
  • @RemyLebeau On all reasonable systems, they're equal to each other. – Barmar Oct 28 '21 at 20:15
  • There is no recv call in this code... – user253751 Oct 29 '21 at 09:39

0 Answers0