Hi there,
I write a code using socket to realize multiple message exchanges between a client and a server (i.e., a protocol running between A and B). But when I use recv() on a client to receive a message from a server, it turned out that the returned receive size is not what I ask for, and of course the whole program is wrong. Why does this happen? How to solve it?

Below is my code snippet.

......
bytesRecv = recv(recv_socket, recv_buff, 1000, 0);
        if(bytesRecv == SOCKET_ERROR)
           printf(" RECVBIG recv() error %ld.\n", WSAGetLastError());
        else
			printf(" RECVBIG recv() OK - Bytes received: %ld\n", bytesRecv);
......

I use the above code, but it shows that:

RECVBIG recv() OK - Bytes received: 260.

,and in the next call to recv, it shows that:

RECVBIG recv() OK - Bytes received: 740.

Not all calls to recv() are wrong, some of them work well. Also, client and server use the same recv() code snippet, but all recv() calls at the server's side are correct.

What's the problem?

> Why does this happen?
Because TCP is a stream protocol. All it guarantees is the order of the information. Breaking that into packets is your problem.

You might send
"hello world\n"
"bye world\n"
in two separate send calls

but on any given test, you might get
"hello world\nbye"
" world\n"

or
"h"
"ello worl"
"d\nbye"
" world\n"

or any other fragmentation.

The point is, all the information is as you sent it, just broken up into different sized packets (specifically, NOT the ones you sent).

> How to solve it?
Find some way to encode the packet information into the sender, then use that at the receiver.
- a delimiter like \n perhaps
- or a size followed by payload.

There is a best techinque to receive the data:

int size_to_recv = 100;
while(size_to_recv)
{
	int r = recv(sock, buf, size_to_recv, 0);
	if(r <= 0)
		break; //socket closed or an error occurred
	size_to_recv -= r;
}

The main reason for this while loop is that 'r' may be less than 'size_to_recv' - the requested amount of data to receive.

This is the code to receive the exact amount of data. You can send the number to the client by send(sock, &size, sizeof(int), 0); . There are many ways to implement this.

Just don't forget to check the return value of recv() function.

Thanks everyone. I solved the problem using suggestions provided. They are really helpful:)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.