Como usar o select() nos 'sockets' correctamente?

Estou a tentar perceber o que estou a fazer de errado.

setup_server_socket chamadas bind e listen e configura o 'socket' para o modo de não-bloqueio.

os seguintes blocos de código na chamada select parece, não avançando para FD_ISSET. Tentei ligar um cliente e parece ter sucesso, mas nunca devolve nada.

Qual é a maneira correcta de fazer isto?

...
int listenfd = setup_server_socket( serverPort );

if( -1 == listenfd )
    return 1;

fd_set read_fds;
FD_ZERO(&read_fds);
int fdmax = listenfd;


// loop forever
while( 1 )
{
    if (select(fdmax+1, &read_fds, NULL,NULL,NULL) == -1){
        perror("select");
        exit(4);
    }

    for (int i = 0; i<= fdmax; i++){
        printf("Testing: %d, %d\n", i, FD_ISSET(i,&read_fds));

    }return 0;
...
Author: cadaniluk, 2015-09-22

2 answers

Leia várias vezes seleccione(2), poll (2) (BTW, você deve preferir poll ao obsoleto select, que não lida com descritores de ficheiros maiores que __FD_SETSIZE, ou seja, 1024 no meu sistema Linux/Debian/x86-64).

Depois:

fd_set read_fds;
FD_ZERO(&read_fds);
int fdmax = listenfd;
FD_SET(listenfd, &read_fds);

Deve ir para dentro o laço while(1), antes de chamar select. BTW, eu recomendo usar poll em vez de select

Leia também sobre o problema de C10k

Não te esqueças que está a mudar de ideias. fd_set - s (e normalmente quer que eles não estejam vazios)...

Talvez usar strace(1)

Leia também programação Linux avançada (é um livro livre que você também pode ler no papel, ou baixar de vários outros lugares, por exemplo isto etc...)

 2
Author: Basile Starynkevitch, 2018-02-14 13:41:56

Aqui está um exemplo (aparado) de usar select ()

INT32    selectStatus;                                 /* select() return code */

char     tempreport[ 256 ] = {'\0'};

struct   timeval tv;

fd_set   fdread;
//fd_set   fdwrite;
//fd_set   fdexcep;



// note:
//  must try to read report until no report available 
// so have latest report in buffer
do
{
    /* Note: timeout must be (re)set every time before call to select() */
    tv.tv_sec = 1;
    tv.tv_usec = 0;


    FD_ZERO(&fdread);
    FD_SET( FD, &fdread );

    selectStatus = select(FD+1, &fdread, NULL, NULL, &tv);

    switch( selectStatus )
    {
        case -1:
            ....
            break;

        case 0:
            // timeout, I.E. nothing to read
            ....
            break;

        default: /* available to read */

            memset(tempreport, 0x00, sizeof(tempreport) );
            readStatus = read_UDP_socket( FD, tempreport, sizeof(tempreport), &readCount );

            break;
    } // end switch( selectStatus )
} while( (0 < selectStatus)&&(eRS_Success == readStatus ) );
 // exit loop on select timeout or select error or read failure

Notas:

eRS_Success is an entry from an enum used for various return codes
read_UDP_socket() is a local function
 0
Author: user3629249, 2015-09-23 16:16:03