0

I am writing the client side of the Socket. When there is something to read my code works fine but when there is nothing to read, the recv never returns. Help please.

Code:

m_socket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in dest;

if ( m_socket )
{
  memset(&dest, 0, sizeof(dest));                /* zero the struct */
  dest.sin_family = AF_INET;
  dest.sin_addr.s_addr = inet_addr(address); /* set destination IP number */ 
  dest.sin_port = htons(port);

  if (connect(m_socket, (struct sockaddr *)&dest, sizeof(struct sockaddr)) == SOCKET_ERROR)
  {
    return false;
  }
  else
  {
    std::vector<char> inStartup1(2);
    int recvReturn = recv(Socket, &inStartup1.at(0), inStartup1.size(), 0);
  }
user2837961
  • 1,505
  • 3
  • 27
  • 67
  • 1
    [I wrote an answer about that](http://stackoverflow.com/questions/2843277/c-winsock-p2p/2920787#2920787). It's simply because `recv` is blocking. The thing to find out is if there is data currently waiting. – default Nov 12 '14 at 08:56
  • What help do you need exactly? You kind of forgot to ask a question. – David Schwartz Nov 12 '14 at 10:09

2 Answers2

3

recv is a blocking call. This would help you:-

The recv() call is normally used only on a connected socket.It returns the length of the message on successful completion. If a message is too long to fit in the supplied buffer, excess bytes may be discarded DEPENDING on the type of socket the message is received from.

If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking, in which case the value -1 is returned and the external variable errno is set to EAGAIN or EWOULDBLOCK. The receive calls normally return any data available, up to the requested amount, rather than waiting for receipt of the full amount requested.

user207421
  • 305,947
  • 44
  • 307
  • 483
ravi
  • 10,994
  • 1
  • 18
  • 36
  • How do I make the socket non-blocking? – user2837961 Nov 12 '14 at 09:04
  • The `recv()` call *never* waits for receipt of the full amount requested. It blocks while no data is available, then returns whatever data had been received at that point. No 'normally' about it. – user207421 Nov 12 '14 at 09:21
0

Taking this one step further, on a server this is how you would correctly handle a connection (socket or serial port does not matter):

  1. make the socket/port non-blocking: this is the first important step; it means that recv() will read what is available (if anything) and return the number of read bytes or -1 in case of an error.
  2. use select(), with a timeout, to find out when data becomes available. So now you wait for a certain amount of time for data to become available and than read it.
  3. The next problem to handle is making sure you read the full message. Since there is no guarantee that the whole message will be available when you call recv(), you need to save whatever is available and go back to select() and wait for the next data to become available.
  4. Put everything in a while(cond) construct to make sure you read all the data.

The condition in the while is the only thing left to figure out - you either know the length of the expected message or you use some delimiters to mark the end of the message.

Hope this helps!

Pandrei
  • 4,843
  • 3
  • 27
  • 44
  • 'make the socket/port non-blocking: this is the first important step' - kinda makes you wonder why blocking calls are available at all, doesn't it? – Martin James Nov 12 '14 at 18:34
  • depends on the application - generally when either end of the connection can terminate at any time you need to make sure your application does not hang. Personally I use blocking calls when I can guarantee the order of events, and that's only in my test applications. – Pandrei Nov 13 '14 at 09:34