Sending several lines of data through socket

I have this problem:
I have a data structure called DACT, that I convert into a string line and send to another computer. I have a file full of DACTs, and I need to send them all to another computer.
When I send only 100, it works fine, but when I send more, like 500, a bug happens:
Some lines are sent once (checked), but received twice. Plus, after a line is read twice, the next 10-20 lines are read mistakenly - always 143 bytes are sent, but it receives only the last 120-100 (sometimes less) bytes.

Here is the relevant client (sender) code:
1
2
3
4
5
6
7
8
9
10
11
12
13
for (sendIterator = sendList.begin(); sendIterator != sendList.end(); sendIterator++)
{
   dact2str(&*sendIterator, buffer);
   buffer_length = sizeof buffer;

   bytes_sent = send(sock, buffer, buffer_length, 0);
   cout << "Bytes sent: " << bytes_sent << endl;

   if (bytes_sent < 0)
   {
   	Die(strerror(errno));
   }
}


And this is the relevant receiver code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
while (true)
{
	recsize = recv(connectFd, (void *) buffer, 143, 0);

	if (recsize < 0)
	{
		fprintf(stderr, "%s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	else if (recsize == 0)
	{
		break;
	}

	wline_dact = buffer;

	if (wline_dact.size() < 142)
	{
		cout
			<< "Invalid Dact. Expected size: 142. Received size: "
			<< wline_dact.size() << endl;
		continue;
	}

	wline_dact = wline_dact.substr(0, 142);

	DACT dact;
	str2dact(&dact, wline_dact);
	receivedDacts.push_back(dact);
}

Later, in the receiver code, I check if any dact was received more than once. That's how I know what is happening.

Thank you for your attention.
How does the receiver know how much data to recieve? How does it know when it's received a full line?

And then there's that magic 143 ...
Its not magic. The size of the buffer is 143.
char buffer[143];

The receiver receives data untill the sender stops. TCP is a conection oriented protocol. So whenever the sender closes socket, the receiver gets 0 bytes.
Before having this bug, the client used to send the number of lines to be passed. But, because of this problem, i made some changes in the code.
Last edited on
The actual size of the string stored in the buffer is 142, but the array has one extra byte for the \0 char.
Last edited on
man recv shows:

The recv() function shall return the length of the message written to the buffer pointed to by the buffer argument.

this result may be less than the 143 that you expect.

suppose on your first pass, Line 3 gets recsize of 5, what do you think will happen on Line 15?

you must set up your loop and your concatenation contained in wline_dact in such a way that it can handle recv() of less than your full expected length.
Last edited on
Hmm... That's quite obvious but i didn't see it.
I will test it.
Thank you very much and sorry for asking stupid questions. =P

Ill test it and mark as solved if that was the problem.
I wasn't being naive with my questions, I wanted you to think about what you are doing.

TCP is a stream protocol, there is no end of stirng marker. If you send a bunch of stuff, the sender and receiver must agree on how to detect the end of record. Are both sides processing 143 bytes at a time?

You do realise that send may not send all the data, and correspondingly recv may not get all the data in one go, right?

If 143 is special, make up some constant that has that value and refer to that. Don't litter your code with magic numbers.
I realised why you asked those questions.
That \0 character was intended for internal control, not for TPC/IP.
And I know it's not good to have 'magic numbers' on my code. I leaned it so you could understand better.
Finally, I realised that send may not send all the data, and correspondingly recv may not get all the data in one go, as said kfmfe04, right before I thanked him.

Thank you for answering my question. I appreciate it. Really.
Because you have no obligation to help a new C++ programmer.
But you just don't need to be rude.

Last edited on
Topic archived. No new replies allowed.