2
votes

I starts learning TCP protocol from internet and having some experiments. After I read an article from http://www.diffen.com/difference/TCP_vs_UDP

"TCP is more reliable since it manages message acknowledgment and retransmissions in case of lost parts. Thus there is absolutely no missing data."

Then I do my experiment, I write a block of code with TCP socket:

while( ! EOF (file))
{
   data = read_from(file, 5KB); //read 5KB from file
   write(data, socket); //write data to socket to send
}

I think it's good because "TCP is reliable" and it "retransmissions lost parts"... But it's not good at all. A small file is OK but when it comes to about 2MB, sometimes it's OK but not always...

Now, I try another one:

while( ! EOF (file))
{
   wait_for_ACK();//or sleep 5 seconds
   data = read_from(file, 5KB); //read 5KB from file
   write(data, socket); //write data to socket to send
}

It's good now...

All I can think of is that the 1st one fails because of: 1. buffer overflow on sender because the sending rate is slower than the writing rate of the program (the sending rate is controlled by TCP) 2. Maybe the sending rate is greater than writing rate but some packets are lost (after some retransmission, still fails and then TCP gives up...)

Any ideas? Thanks.

2
Hmm, what OS and programming language is this code for? - thkala
@thkala +1, that "5KB" really intrigues me. - Mauricio
It's C on Linux... 5KB is an example. Instead of 5KB, each time I can read 1KB from a file then send it, then another 1KB, so on... - user397232
C... on Linux. Last time I heard "5KB" was not a valid C/C++/Java identifier, write() has three arguments and wait_for_ACK() and read_from() do not exist in POSIX. This is more like pseudo-code from somewhere. Care to show us the actual code that you tried? - thkala
At first, I don't think it's difficult to understand my pseudo code. But I think I'm wrong. Sorry about it. Anyway, the answer of 6502 below is kinda what I need. Thanks. - user397232

2 Answers

5
votes

TCP will ensure that you don't lose data but you should check how many bytes actually got accepted for transmission... the typical loop is

while (size > 0)
{
    int sz = send(socket, bufptr, size, 0);
    if (sz == -1) ... whoops, error ...
    size -= sz; bufptr += sz;
}

when the send call accepts some data from your program then it's a job of the OS to get that to destination (including retransmission), but the buffer for sending may be smaller than the size you need to send, and that's why the resulting sz (number of bytes accepted for transmission) may be less than size.

It's also important to consider that sending is asynchronous, i.e. after the send function returns the data is not already at the destination, it's has been only assigned to the TCP transport system to be delivered. If you want to know when it will be received then you'll have to use other systems (e.g. a reply message from your counterpart).

2
votes

You have to check write(socket) to make sure it writes what you ask. Loop until you've sent everything or you've calculated a time out. Do not use indefinite timeouts on socket read/write. You're asking for trouble if you do, especially on Windows.