简体   繁体   中英

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?

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

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.

如果时间在您的应用程序中无关紧要,您可以在两条消息之间添加一个像 sleep(5) 这样的短时间间隔。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM