【问题标题】:TCP socket sending less number of bytesTCP 套接字发送更少的字节数
【发布时间】:2014-05-21 23:38:49
【问题描述】:

我正在尝试使用 boost.asio 库发送大量字节,如下所示:

void tcp_send(boost::asio::io_service &io, const char *dst_ip, uint16 dst_port)
{
    uint8 *sbuff;
    size_t slen;
    ip::tcp::socket sock(io);

    sock.connect(ip::tcp::endpoint(ip::address::from_string(dst_ip), dst_port));

    sbuff = new uint8[100412];
    sbuff[0] = 67;
    sbuff[1] = 193;
    sbuff[2] = 136;
    sbuff[3] = 60;

    boost::asio::async_write(sock, boost::asio::buffer(sbuff, 100412),
             boost::bind((&send_handler), placeholders::error));
}

当我使用 Wireshark 检查传输的字节数时,发送方始终只发送 65536 字节的数据,不包括 TCP 标头字节。那么可能是什么问题呢? 有没有需要修改的参数。

我在 linux ubuntu 上运行该应用程序。好像传输的最大字节数是2^16。

【问题讨论】:

    标签: c++ linux sockets boost-asio


    【解决方案1】:

    TCP 是一个流。 IP 数据报或以太网帧中出现多少字节应该与您无关。

    成功调用send 并不一定意味着数据已经发送;只是 TCP 堆栈接受了数据并承诺发送它(除非您指定 PSH)。

    【讨论】:

    • 那么在我的情况下我应该怎么做才能让所有的 100412 字节都消失呢?实际上我直接使用 Berkeley 套接字时没有问题,但现在我在使用 boost 包装器时遇到了这个问题。
    • 不确定您是如何实现其余部分的,但您可以尝试在 send_handler 中跟踪它。
    • 请你检查我的新编辑我提供了wireshark输出。 send_handler 仅用于错误处理
    • send_handler 在发送完成时调用,无论发送成功与否。让它告诉您是否发送了完整的缓冲区,或者发送是否失败。很有可能,它在发送 65536 个字节后失败。 TCP 无法在单个数据包中发送 100412 字节,因此 async_write() 应该发送多个数据包,直到 buffer 用尽或发生错误。
    • 我现在尝试用boost::asio::write替换boost::asio::async_write(),操作成功。我能够看到wireshark中的所有字节。谁能向我解释发生了什么? @Remy 你是对的,但我在 send_handler 中根本没有收到任何错误。
    【解决方案2】:

    我找到了问题的根源。首先,我试图使用 tcp_Send 函数发送消息,在它从调用返回后,我存在程序。因此,TCP 堆栈没有足够的时间来发送其缓冲区中的所有数据包。所以我应该给它一些时间。

    现在在第二次试用中,我在发送消息后保持应用程序运行,但现在我在send_handler 中遇到错误,其中显示bad file descriptor。这是因为声明的套接字在退出tcp_send 函数后被销毁。所以为了解决这个问题,我应该将套接字定义为一个指针。或者最好的办法是使用 write 而不是 async_Write

    【讨论】:

    • 不会造成数据丢失。当您销毁ip::tcp::socket 时,底层套接字将关闭,但所有待处理的数据仍保留在套接字发送缓冲区中以进行最终传输,然后按顺序关闭(TCP FIN)。但是,在您的程序退出时,它可能尚未全部发送。
    • 我最近没有测试过它,但它曾经是在 Windows(XP 和更早版本)中退出进程会丢弃网络堆栈中任何未发送的数据,而在 *nix 系统上数据会最终还是会被发送。一个真正的 PITA 适合 Windows 程序员,因为没有很好的方法来询问数据是否真的被发送了。
    猜你喜欢
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多