geraldCelente
geraldCelente

Reputation: 995

Multiple calls to send() are merged into one call to recv()

I have a client-server application.

The client is sending a string followed by an integer using two distinct send() calls. These two data are supposed to be stored into two different variables on the server.

The problem is that both variables sent are received on recv() call. Therefore, the two strings sent by the two distinct send()s are chained and stored in the buffer of the first recv().

server.c:

printf("Incoming connection from client %s:%i accepted\n",inet_ntoa(clientSocketAddress.sin_addr),ntohs(clientSocketAddress.sin_port));


memset(buffer,0,sizeof(buffer));
int sizeofMessage;
if ((recv(clientSocket,buffer,MAXBUFFERSIZE,0)==sizeofMessage)<0)
{
  printf("recv failed.");
  closesocket(serverSocket);
  clearWinsock();
  return EXIT_FAILURE;
}

char* Name=buffer;
printf("Name: %s\n",Name);

if ((recv(clientSocket,buffer,MAXBUFFERSIZE,0))<0)
{
  printf("bind failed.");

  closesocket(serverSocket);
  clearWinsock();
  return EXIT_FAILURE;
}

int integer=ntohs(atoi(buffer));
printf("integer: %i\n",intero);

client.c:

if (send(clientSocket,Name,strlen(Name),0)!=strlen(Name))
{
  printf("send failed");

  closesocket(clientSocket);
  clearWinsock();
  return EXIT_FAILURE;
}

printf("client send: %s",Name);

int age=35;
itoa(htons(age),buffer,10);
sizeofBuffer=strlen(buffer);
if (send(clientSocket,buffer,sizeofBuffer,0)!=sizeofBuffer)
{
  printf("bind failed.");

  closesocket(clientSocket);
  clearWinsock();
  return EXIT_FAILURE;
}

How can I fix it? What am I doing wrong?

Upvotes: 9

Views: 9770

Answers (3)

user5280911
user5280911

Reputation: 763

You can add a short time interval like sleep(5) between two messages, if time does not matter too much in your application.

Upvotes: 0

alk
alk

Reputation: 70981

TCP is a streaming protocol. It is not aware at all of any kind of "message" boundaries. It does not add such information dependend on single calls to send().

Due to those facts any number of send()s on the sender side can lead to any number of recv()s (up to the number of bytes sent) on the receiver side.

To get around this behaviour define and implement an application level protocol to distinguish the different "messages" that had been sent.

One cannot rely on recv()/send() receiving/sending as much bytes as those two functions were told to receive/send. It is an essential necessity to check their return value to learn how much bytes those functions actually received/sent and loop around them until all data that was intended to be received/sent had been received/sent.

For examples how this "looping" could be done

Upvotes: 11

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84239

This is how TCP works. Treat it as a byte stream. Put some basic protocol on top of it - delimit you application messages with some known byte value, or prepend your messages with length field.

Or switch to UDP, which gives you datagram semantics you are looking for, if you can tolerate/recover from occasional packet loss.

Upvotes: 2

Related Questions