Thread: How does select work when recv-ing?

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    13

    How does select work when recv-ing?

    I am trying to learn socket programming but I am having trouble with partial recv-ing.

    I want to get all the text in yahoo.com/index.html.

    Code:
        TCPClient client("www.yahoo.com",80);
    
        client.setTimeOut(1,0);
    
        client.write("GET http://www.yahoo.com/index.html HTTP/1.1\nHost: www.yahoo.com\n\n");
    
        cout << client.read();
    I only get 512 bytes at a time using my recv function so that is why I loop it.

    During the first few loops the select function returns 1 and the recv function returns 512. After all the text has been downloaded from yahoo the select function keeps returning 1 and the recv function returns 0. Therefore it gets stuck in an infinite while loop.

    I thought the select function returned 0 when the recv function didn't have any data to return and would also return 0. Should I just set the while loop to stop when size equals 0 or I am using these functions wrong? I meant for the while loop to stop when there was no more data to receive from the the socket, which is what I though select told me. How should I do this correctly?

    Code:
    std::string TCPClient::read()
    {
        std::string buffer;
        char b[512];
        int size = 0;
    
        FD_ZERO(&mReadFds);
        FD_SET(mSocket, &mReadFds);
    
        int error = select(mSocket + 1, &mReadFds, 0, 0, &mTimeOut);
    
        while (error > 0)
        {
            if(FD_ISSET(mSocket, &mReadFds))
            {
                size = recv(mSocket, b, 512, 0);
                if (size == SOCKET_ERROR)
                {
                    mState = CS_BROKEN;
                    return buffer;
                }
    
                b[size] = 0;
                buffer += b;
            }
    
            FD_ZERO(&mReadFds);
            FD_SET(mSocket, &mReadFds);
    
            error = select(mSocket + 1, &mReadFds, 0, 0, &mTimeOut);
    
            std::cout << "error: " << error << std::endl;
            std::cout << "size:  " << size << std::endl;
    
        }
    
        if (error == SOCKET_ERROR)
        {
            mState = CS_BROKEN;
            return buffer;
        }
    
        mState = CS_CONNECTED;
        return buffer;
    }
    Thanks for any help.
    Last edited by newtocpp; 11-30-2007 at 01:17 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Because a recv() returning 0 is special perhaps?
    Maybe read the manual to find out why.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    13
    Thank you for the help.

    I think I have fixed it. I have found in the beej manual that if select returns 1 and recv returns 0 then the connection on the other side has been closed.

    What was confusing me was that when the connection on the other side didn't close select would return 0 if there was no data for recv to get.

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Just because select() tells you that no data is available at this time, doesn't mean no more data is coming later. This is why select() can't be used to know when a connection is closed. You have to look for recv() to return 0 to detect that.

    Also, select() returning true doesn't actually mean that data is available. It means that a call to recv() won't block. These are two different things.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why don't the tutorials on this site work on my computer?
    By jsrig88 in forum C++ Programming
    Replies: 3
    Last Post: 05-15-2006, 10:39 PM
  2. select model sockets
    By l2u in forum Networking/Device Communication
    Replies: 1
    Last Post: 05-15-2006, 08:18 AM
  3. Problems in getting OpenGL to work
    By zonf in forum C Programming
    Replies: 5
    Last Post: 02-13-2006, 04:48 AM
  4. Problems with using pipe(...); on select(...);
    By ne2000 in forum Linux Programming
    Replies: 1
    Last Post: 01-10-2006, 05:09 PM
  5. scandir select function
    By dsl24 in forum C Programming
    Replies: 3
    Last Post: 04-12-2002, 10:58 AM