【问题标题】:TCP socket questionTCP套接字问题
【发布时间】:2011-06-17 16:17:42
【问题描述】:

我开始从互联网上学习 TCP 协议并进行一些实验。看了http://www.diffen.com/difference/TCP_vs_UDP的一篇文章后

“TCP 更可靠,因为它在丢失部分的情况下管理消息确认和重传。因此绝对不会丢失数据。”

那我做实验,我用TCP socket写了一段代码:

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放弃……)

有什么想法吗? 谢谢。

【问题讨论】:

  • 嗯,这段代码是用于什么操作系统和编程语言的?
  • @thkala +1,“5KB”真的很吸引我。
  • Linux 上是 C...5KB 就是一个例子。每次我可以从文件中读取 1KB 然后发送,而不是 5KB,然后再发送 1KB,依此类推...
  • C... 在 Linux 上。上次我听说“5KB”不是一个有效的 C/C++/Java 标识符,write() 有三个参数,wait_for_ACK()read_from() 在 POSIX 中不存在。这更像是来自 somewhere 的伪代码。愿意向我们展示您尝试过的实际代码吗?
  • 起初,我认为我的伪代码并不难理解。但我觉得我错了。对不起。无论如何,下面6502的答案是我需要的。谢谢。

标签: sockets tcp


【解决方案1】:

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 传输系统。如果您想知道何时收到,则必须使用其他系统(例如对方的回复消息)。

【讨论】:

  • 如果在一些重传之后仍然丢失了一个数据包怎么办?在这种情况下,TCP 是否返回任何错误消息以便我可以捕获它?如果我在缓冲区已满时继续写入 TCP 缓冲区,它肯定会溢出,在这种情况下,sz = 0?
  • @user397232:在这种情况下,您会收到错误消息(并且 sz=-1)。当缓冲区超过某个阈值时,send() 将阻塞,使您的程序等待直到发送一些数据。
【解决方案2】:

您必须检查write(socket) 以确保它写出了您的要求。 循环直到您发送所有内容或计算出超时时间。 不要在套接字读/写上使用无限超时。如果这样做,您就是在自找麻烦,尤其是在 Windows 上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多