我开始从互联网上学习 TCP 协议(protocol)并进行一些实验。在我阅读了一篇来自 http://www.diffen.com/difference/TCP_vs_UDP 的文章之后
“TCP 更可靠,因为它在丢失部分的情况下管理消息确认和重传。因此绝对不会丢失数据。”
然后我做我的实验,我用 TCP 套接字写了一段代码:
while( ! EOF (file))
{
data = read_from(file, 5KB); //read 5KB from file
write(data, socket); //write data to socket to send
}
我认为这很好,因为“TCP 是可靠的”并且它“重传丢失的部分”……但它一点也不好。一个小文件还可以,但是当涉及到大约 2MB 时,有时还可以,但并非总是...
现在,我尝试另一个:
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
}
现在好了...
我能想到的是第一个失败是因为: 1.发送端缓冲区溢出,因为发送速率比程序写入速率慢(发送速率由TCP控制) 2. 可能是发送速率大于写入速率但是有些包丢失了(经过一些重传,仍然失败然后TCP放弃...)
有什么想法吗? 谢谢。
最佳答案
TCP 将确保您不会丢失数据,但您应该检查实际接受传输的字节数...典型的循环是
while (size > 0)
{
int sz = send(socket, bufptr, size, 0);
if (sz == -1) ... whoops, error ...
size -= sz; bufptr += sz;
}
当 send
调用从您的程序中接受一些数据时,操作系统会将其发送到目的地(包括重新传输),但发送缓冲区可能小于您需要的大小发送,这就是为什么生成的 sz
(接受传输的字节数)可能小于 size
。
同样重要的是要考虑到发送是异步的,即在 send
函数返回后,数据还没有到达目的地,它只是被分配给 TCP 传输系统进行传递。如果你想知道什么时候会收到,那么你将不得不使用其他系统(例如来自对方的回复消息)。
关于sockets - TCP套接字问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4835893/