【问题标题】:Parts of TCP packet lossTCP部分丢包
【发布时间】:2016-05-04 05:25:17
【问题描述】:

我正在编写一个 TCP 服务器。我在本地主机上工作正常。当我远程部署它时,一些字节在到达目的地的途中丢失了。

我在 localhost 和远程使用 netcat 并对两个输出进行了比较,丢失的字节是确定性的。

所以我怀疑这是丢包,因为同一个包丢失的可能性很小。

我试图将我在套接字上的写入大小减少到 1000 字节,但我仍然遇到这个问题。

这种错误有什么常见的原因吗?

我可以发布代码,但它只是来自 Boost asio 库的 socket.send。我不确定错误是否来自代码,否则它将无法在 localhost 上运行。

提前感谢您的帮助

【问题讨论】:

  • Tcp 是无损的。它在规范tools.ietf.org/html/rfc793 中。你确定你使用的是 tcp 还是问题出在其他地方
  • 最常见的原因是没有检查send() 的返回。如果你调用send(sck, data, 1000, 0),它返回990,你没有检查返回值并重新发送剩余的10个字节,那么你将丢失它们。 recv() 也是如此。
  • @Hd Heal 我知道损失更少。这就是我在这里问的原因
  • @rodrigo 。为什么 boost:asio 不处理这种事情。我的意思是谁不想重新发送他们的数据?
  • @DARK_DUCK:我说的是一般意义上的send(),而不是asio。但是来自文档:send 操作可能不会将所有数据传输到对等方。如果您需要确保在异步操作完成之前写入所有数据,请考虑使用async_write 函数。

标签: c++ sockets networking tcp boost-asio


【解决方案1】:

当使用套接字和函数send() 发送数据时,它返回实际发送的字节数,这可能小于您传递给函数的数量。

如果您使用阻塞 I/O,有时会使用这样的函数:

ssize_t send_all(int socket, const void *data, size_t len)
{
    while (len > 0)
    {
        ssize_t r = send(socket, data, len, 0);
        if (r < 0)
        { //you could also return -1 on EINTR
            if (errno == EINTR)
                continue;
            else
                return -1;
        }
        len -= r;
        data = (const char*)data + r;
    }
    return len;
}

由于您使用的是boost::asio,而不是原始套接字,因此该方法没有用。但是在async_send 文档中,您会得到您所需要的:

发送操作可能不会将所有数据传输到对等方。如果您需要确保在异步操作完成之前写入所有数据,请考虑使用async_write 函数。

【讨论】:

    猜你喜欢
    • 2021-12-07
    • 2018-03-18
    • 2014-05-09
    • 1970-01-01
    • 2014-07-13
    • 2019-07-29
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多