csocketsrecvposix-select

Using select on a socket doesn't return


I don't know why the select function doesn't return any result. I put the server in execution with this command:

./server 5555

and I try to send any character from another terminal, using:

nc 127.0.0.1 5555

and

any string to send

This is the source code of the server.c

#include <stdlib.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>

#define MAXSIZE 1000

int main(int argc, char **argv) {
    int socketfd, connectedfd, maxfd;
    int ris, i, len, ris1, sent, opt;
    struct sockaddr_in serverS, clientS;
    short int localServerPort;
    fd_set rdfs, wrfs;
    char buffer[MAXSIZE];

    if (argc != 2) {
        printf("necessario un parametro PORTNUMBER");
        exit(1);
    } else {
        localServerPort = atoi(argv[1]);
    }
    
    socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if (socketfd < 0) {
        printf("socket() error\n");
        exit(1);
    }
    
    opt = 1;
    ris = setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
    if (ris < 0)  {
        printf ("setsockopt() SO_REUSEADDR failed, Err: %d \"%s\"\n", errno,strerror(errno));
        exit(1);
    }
    
    memset(&serverS, 0, sizeof(serverS));
    serverS.sin_family = AF_INET;
    serverS.sin_addr.s_addr = htonl(INADDR_ANY);
    serverS.sin_port = htons(localServerPort);
    ris = bind(socketfd, (struct sockaddr*)&serverS, sizeof(serverS));
    if (ris < 0) {
        printf("bind() error");
        exit(1);
    }
    
    ris = listen(socketfd, 10);
    if (ris < 0) {
        printf("listen() error");
        exit(1);
    }
        
    len = sizeof(clientS);
    connectedfd = accept(socketfd, (struct sockaddr*)&clientS, &len);
    if (connectedfd < 0) {
        printf("accept() error");
        exit(1);
    } else {
        printf("Connesso con: %s:%d - descrittore: %d\n", inet_ntoa(clientS.sin_addr), ntohs(clientS.sin_port), connectedfd);
    }
    
    fd_set tempset;
    FD_ZERO(&rdfs);
    //FD_ZERO(&wrfs);
    FD_SET(connectedfd, &rdfs);
    maxfd = connectedfd + 1;
    
    while (1) {
        printf("Select...\n");
        ris = select(connectedfd, &rdfs, NULL, NULL, NULL);
        printf("test\n");
        if (ris == 0) {
            printf("select() timeout error\n");
        } else if (ris < 0 && errno != EINTR) {         
            printf("select() error\n");
        } else if (ris > 0) {
            printf("test ris > 0\n");
            for (i = 0; i < maxfd+1; i++) {
                 if (FD_ISSET(i, &rdfs)) {
                    do {
                    ris = recv(i, buffer, MAXSIZE, 0);
                 } while (ris == -1 && errno == EINTR);
                 
                 if (ris > 0) {
                    buffer[ris] = 0;
                    printf("Echoing: %s\n", buffer);
                    sent = 0;

                    do {
                       ris1 = send(i, buffer+sent, ris-sent, MSG_NOSIGNAL);
                       if (ris1 > 0)
                          sent += ris1;
                       else if (ris1 < 0 && errno != EINTR);
                          break;
                     } while (ris > sent);

                 }
                 else if (ris == 0) {
                    close(i);
                    FD_CLR(i, &rdfs);
                 }
                 else {
                    printf("Error in recv(): %s\n", strerror(errno));
                 }      
                 }
            }
        }       
    }
    
    return(0);
}

Why does the execution remain locked at "Select...\n"?


Solution

  • From http://linux.die.net/man/2/select, the first param passed should be the highest-numbered file descriptor in any of the three sets (read/write/exception), plus 1. I would try the following:

        ris = select(connectedfd+1, &rdfs, NULL, NULL, NULL);