Thread: recv always returns 1

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    930

    recv always returns 1

    I cant see why my recv() is always returning 1, no more no less.

    So it wont ever come out of while().

    Code:
     
    while(i = recv(mySocket, buffer, sizeof buffer, 0 ) >0)
    {
               str1 = buffer;
               str2 += str1;
               cout << i << endl;
    }
    Last edited by Ducky; 12-10-2009 at 10:30 AM.
    Using Windows 10 with Code Blocks and MingW.

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Bad operator precedence. You need:

    Code:
     
    while( ( i = recv(mySocket, buffer, sizeof buffer, 0 ) ) >0)
    {
               str1 = buffer;
               str2 += str1;
               cout << i << endl;
    }
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    930
    Ah, cool, thank you Brewbuck!

    However 'i' isnt 1 anymore, it always stays in the loop until it is disconnected from the client.

    Shouldnt blocking sockets stop blocking once they recieved data?

    I dont understand why would it stay in the loop.
    Last edited by Ducky; 12-10-2009 at 02:03 PM.
    Using Windows 10 with Code Blocks and MingW.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Ducky View Post
    Shouldnt blocking sockets stop blocking once they recieved data?
    No, that would be a non-blocking socket. It waits until there is data to recv, so this kind of loop will only end on an error (which would cause a recv of -1).

    However, it works perfect with a NON_BLOCK socket.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Dec 2009
    Location
    /dev/pts/0
    Posts
    29
    Quote Originally Posted by MK27 View Post
    No, that would be a non-blocking socket. It waits until there is data to recv, so this kind of loop will only end on an error (which would cause a recv of -1).

    However, it works perfect with a NON_BLOCK socket.
    Now, what the heck is a NON_BLOCK socket? Do you mean an O_NONBLOCK socket? (See the [url=http://linux.die.net/man/2/open]man page for open()[/b] for more details). You can also use fcntl to change the flags on a file descriptor after you've opened it.
    -- strange

    There is no Darkness in Eternity
    Only Light too dim for us to see

  6. #6
    Registered User
    Join Date
    Dec 2007
    Posts
    930
    Thanks for the help MK27 and Strange!

    No its not working against >-1 either.

    I guess the only way is to first send the size and then the data if we have a lot to send.
    Last edited by Ducky; 12-14-2009 at 07:24 AM.
    Using Windows 10 with Code Blocks and MingW.

  7. #7
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875

    Blockiing vs Non-blocking sockets

    Blocking sockets do essentially this:
    Code:
         recv(sockDescriptor, sockBuf, sockBufSize); // waits forever for input if non comes
    In other words, the recv() call "blocks" the current thread of execution until there is something to read.

    Note that the thread or process this call is in is essentially halted until there is activity on the socket, behavior that is often undesirable for a number of reasons. For anything non-trivial try non-blocking sockets are called for, first make sure there is something to read with select():
    Code:
    while(!bExitFlag)
    {
        struct timeval tv;
        fd_set readfds;
        int sockDescCount = 0;
        tv.tv_sec = 2;
        tv.tv_usec = 500000;
    
        FD_ZERO(&readfds);
        FD_SET(sockDescriptor, &readfds);
        sockDescCount++;
        // don't care about writefds and exceptfds:
        select(sockDescCount+1, &readfds, NULL, NULL, &tv);
    
        if (FD_ISSET(sockDescriptor, &readfds))
        {
             printf("Socket has data!\n");
             recv(sockDescriptor, workBuf, workBufSize);
             // do something with it
         }
        else
            printf("Timed out so do some other work, check for exit flags, etc.\n");
    }
    Note: this code has been shortened from real code to simply illustrate the use of a non-blocking scheme. Production code would look different. Also it may seem stupid resetting the timeout value every time but (as I found out on a project at work) Linux actually decrements that value so if you just reused the timeout value your timeout would get shorter and shorter every time until it was effectively 0, binding up the CPU, bad juju in any application...
    Last edited by jeffcobb; 12-14-2009 at 12:35 PM. Reason: Not awake yet, forgot some curlies
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by jeffcobb View Post
    Also it may seem stupid resetting the timeout value every time but (as I found out on a project at work) Linux actually decrements that value so if you just reused the timeout value your timeout would get shorter and shorter every time until it was effectively 0, binding up the CPU, bad juju in any application...
    The reason for that behavior is to make it easier to restart select() when a signal interrupts it. In general if some API takes a non-const pointer you should always assume that it could change the value, so it's correct to reset the timeout each time in any case.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  9. #9
    Registered User
    Join Date
    Dec 2007
    Posts
    930
    Thank you Jeff and Brewbuck!

    Can i use select() in a win32(non console) program?
    Using Windows 10 with Code Blocks and MingW.

  10. #10
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    Ducky; my windows socket days are aways behind me now but as I recall, WinSock has their own almost-workalikes for the whole BSD socket layer, of which select() is a part. Might be WinSelect() or something like that. Select() on linux is really powerful because everything is considered a file (network, files, even the sound card) so you can for example put a watch on a file to tell then it has been read from, written to, errored or any combination of the above. Also in Linux there is the poll() function which works differently and so is useful for different things like if you just want to watch a single descriptor (select() you can watch many)...
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  11. #11
    Registered User
    Join Date
    Dec 2007
    Posts
    930
    Cool, thanks Jeff ill look it up.
    Using Windows 10 with Code Blocks and MingW.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. recv() returns 0 the second time
    By Overlord in forum Networking/Device Communication
    Replies: 7
    Last Post: 07-10-2009, 04:09 AM
  2. Question about recv
    By carrotcake1029 in forum Networking/Device Communication
    Replies: 2
    Last Post: 02-26-2009, 02:10 PM
  3. Polynomials and ADT's
    By Emeighty in forum C++ Programming
    Replies: 20
    Last Post: 08-19-2008, 08:32 AM
  4. recv returns with 0
    By napsy in forum Networking/Device Communication
    Replies: 12
    Last Post: 07-28-2008, 07:15 PM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM