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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With