ImbaBalboa
ImbaBalboa

Reputation: 867

C select always detects a socket readable

I looked for an answered on quite similar topic, but I have not find a good answer (I think).

First my code :

fd_set readset;
int result;
    
while(1) {
    FD_ZERO(&readset);
    FD_SET(sock_client, &readset);
    FD_SET(fileno(stdin), &readset);
    result = select(sock_client + 1, &readset, NULL, NULL, NULL);
    
    if (result > 0) {
        if (FD_ISSET(sock_client, &readset)) {
            memset(buffer, 0, sizeof(buffer));
             read(server_socket, buffer, 5000);
            printf("%s", buffer);
        } 
        
        if (FD_ISSET(fileno(stdin), &readset)) {
            memset(msg, 0, sizeof(msg));
            read(fileno(stdin), msg, 5000);
            printf("%s", msg);
        }
    }
}

EDIT (error in the read() corrected):

// socket client
sock_client = do_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

// socket server
server_socket = do_socket(AF_INET, SOCK_STREAM, 0);

// server connexion
do_connect(server_socket, 
    (struct sockaddr *) & addr_sock_host, sizeof(addr_sock_host));

fd_set readset;
int result;
    
while(1) {
    FD_ZERO(&readset);
    FD_SET(sock_client, &readset);
    FD_SET(fileno(stdin), &readset);
    result = select(sock_client + 1, &readset, NULL, NULL, NULL);
    
    if (result > 0) {
        if (FD_ISSET(sock_client, &readset)) {
            memset(buffer, 0, sizeof(buffer));
            int size = read(sock_client, buffer, 5000);
            printf("size : %i\n", size);
        } 
        
        if (FD_ISSET(fileno(stdin), &readset)) {
            memset(msg, 0, sizeof(msg));
            read(fileno(stdin), msg, 5000);
            printf("%s", msg);
        }
    }
}

When I run it :

size : -1
size : -1
size : -1
size : -1
size : -1
size : -1
size : -1
size : -1

... infinitely

END OF EDIT

Actually, select returns always 1 because sock_client is always in readset whereas there is nothing to read on it. Over more, my FD_SET are in the infinite loop. That's why I don't understand how it's possible that sock_client be detected as readable (always)?

Upvotes: 1

Views: 961

Answers (1)

user207421
user207421

Reputation: 311023

You don't need the memset(), and you cannot convince me that reading from the listening socket blocks. The real problem here is that you are:

  • reading from the wrong socket FD, and
  • completely ignoring the value returned by read().

You need to:

  1. Store it in a value.
  2. Compare it to -1, and if so call perror() or one of its friends immediately, and close the socket.
  3. Otherwise, compare it to zero, and if so clos the socket.
  4. Otherwise, use the positive value that must remain as the length of the incoming data. That's why you don't need the memset().

Upvotes: 2

Related Questions