3

A valid socket connection is already established to a server. There's a simple loop designed to continue receiving data until the server stops sending any more. All the documentation indicates that trying recv() too many times should just cause it to return 0 or -1 (depending on the situation). Instead it's killing the thread with some sort of IOError (at the line with the recv call). What am I missing?

Edit: sad is just some stringstream. I promise it has nothing to do with the problem :D

Another Edit: included errno.h and checked for errno codes, to no avail.

do {            
    memset(buffer,0,sizeof(buffer));
    bytes = recv(s,buffer,sizeof(buffer)-40,0);
    sad << buffer;
    Sleep(1);
} while (bytes>0);
TheToolBox
  • 272
  • 2
  • 10

1 Answers1

1

Perhaps you should also check errno, since there might be a permature end to the communication channel.

#include <errno.h>
#include <string.h>

do {            
    memset(buffer,0,sizeof(buffer));
    bytes = recv(s,buffer,sizeof(buffer)-40,0);
    if (errno)
       break;
    sad << buffer;
    Sleep(1);
} while (bytes>0);

if (errno)
   std::cerr << "Premature end of connection: " << strerror(errno) << '\n';
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Tried it, but the thread just dies when the line starting with `bytes =` runs. Including/checking errno didn't change it, although a good thought. – TheToolBox Oct 11 '12 at 00:00
  • Try handling SIGPIPE: http://stackoverflow.com/questions/108183/how-to-prevent-sigpipes-or-handle-them-properly (signals will usually interrupt sleep too, by the way) – sehe Oct 11 '12 at 00:03
  • I just tried a couple of ways, but can't figure out how to force the handling of it. I'm compiling under windows, which I'm sure is the problem as usual. It appears that I have no `SO_NOSIGPIPE`, nor does `signal(SIGPIPE, SIG_IGN);` do it for me. Tried to look up a flag to run with recv to ignore it, but documentation doesn't show anything for it... EDIT: Also rapidly learning the differences between unix and windows implementations of these signals – TheToolBox Oct 11 '12 at 00:19
  • Hmm. That's indeed a bit hairy. I think you've done all the right bits. Can you see about any 'first chance exceptions' (or what does visual studio call them) happening when you run this from within the IDE? Do you have control over the other end of the connection, so you can check that it is still alive? Perhaps replace it with netcat, for testing? – sehe Oct 11 '12 at 00:25
  • Ahhh good call. I think I'm misunderstanding the behavior slightly. The thread just seems to pause (possibly until it actually receives something?). Weird that it gave the parent the go-ahead though. (at least I don't have to deal as much with handling whatever windows likes to throw xD) – TheToolBox Oct 11 '12 at 00:35
  • Tried to set timeout, hoping that would fix it, but no dice :( – TheToolBox Oct 11 '12 at 00:41
  • The thread just seems to pause (possibly until it actually receives something?) - that is normal behaviour. That's what is supposed to happen with blocking sockets. recv() will not return until something happens - data rx, socket closed by peer, timeout or error. I don't understand 'Weird that it gave the parent the go-ahead though' - what go-ahead? I don't see any 'parent' signaling in there? Also, you should not need any sleep() call. – Martin James Oct 14 '12 at 11:03