我开始从互联网学习TCP协议并进行一些实验。在我阅读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放弃......)
有什么想法吗? 感谢。
答案 0 :(得分:5)
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传输系统。如果您想知道什么时候会收到,那么您将不得不使用其他系统(例如来自对方的回复消息)。
答案 1 :(得分:2)
您必须检查write(socket)
以确保它写出您要求的内容。
循环直到你发送了所有内容或者你已经计算出超时。
不要在套接字读/写上使用无限期超时。如果你这样做,你会遇到麻烦,特别是在Windows上。