TCP套接字问题

时间:2011-01-29 08:31:50

标签: sockets tcp

我开始从互联网学习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放弃......)

有什么想法吗? 感谢。

2 个答案:

答案 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上。