Matei
Matei

Reputation: 372

Using select() for socket programming. Problems with FD_ISSET

I'm trying to receive a message from a server but I have some problems. I'm sure that my server code is good because it worked without multiplexing sockets but right now when I'm trying to use select() it doesn't receive anything.

while(1){
    tmp_fds = read_fds;
if (select(fdmax + 1, &tmp_fds, NULL, NULL, NULL) == -1)
          error((char *)"ERROR in select");
if (FD_ISSET (sockfd, &tmp_fds)){
  memset(buffer, 0 , BUFLEN);
  n = recv (sockfd,buffer,BUFLEN,0);
}

This is my code for receiving from the server. What am I doing wrong ? The socket which is used to comunicate with the server is already in read_fds. BUFLEN is 256.

Upvotes: 0

Views: 1856

Answers (2)

Devolus
Devolus

Reputation: 22074

Before calling select, you should clear the FD structure and set the flags you need. After all, when select returns, the bits might be changed from select and when you next time execute the loop they are different than before.

Here is the example that I use for my server that I'm currently implement and this works for sure.

while(sigterm == false)
{
    FD_ZERO(&mReaders);
    FD_ZERO(&mWriters);
    FD_ZERO(&mExceptions);

    FD_SET(fileno(stdin), &mReaders);
    FD_SET(serversocket, &mReaders);
    pret = pselect(FD_SETSIZE, &mReaders, &mWriters, &mExceptions, NULL, &mSignalMask);
    nErrorCode _code = errno;
    if(pret == 0)
    {
        // Timeout occured, but we are not interested in that for now.
        continue;
    }

    if(pret < 0)
    {
        switch(nErrorCode)
        {
            case EINTR:
                cout << "Interrupted: " << pret << "   errno: " << nErrorCode << endl;
            break;

            default:
            {
                cout << "Unknown retval from pselect: " << pret<< "   errno: " << nErrorCode << endl;
            }
        }
        continue;
    }

    if(FD_ISSET(fileno(stdin), &mReaders))
    {
        string s;
        cin >> s;
        cout << "stdin: " << s << endl;
        continue;
    }

    if(FD_ISSET(serversocket, &mReaders))
    {
        // client connected
    }
}

Upvotes: 0

ja_mesa
ja_mesa

Reputation: 1969

Try it this way

while(1)
{
    tmp_fds = read_fds;
    int ret=select(fdmax + 1, &tmp_fds, NULL, NULL, NULL);
    if (ret > 0)
    {
        if (FD_ISSET (sockfd, &tmp_fds))
        {
            // there is no need for the memset
            memset(buffer, 0 , BUFLEN);
            n = recv (sockfd,buffer,BUFLEN,0);
        }
    }
    else
        if (ret < 0) 
        {
           error((char *)"ERROR in select");
           // here you must check what kind of error you received
           // may be you need to close the socket and start over again
           // return;
        }
}

Upvotes: 1

Related Questions