【问题标题】:Flusing TCP after boost::asio::writeboost::asio::write 后刷新 TCP
【发布时间】:2018-09-18 05:26:18
【问题描述】:

我有一个用 boost:.asio 编写的简单服务器

boost::asio::io_context io_context;
tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), port));
tcp::socket socket(io_context);
acceptor.accept(socket);
boost::asio::ip::tcp::no_delay option(true);
socket.set_option(option);

for(int i = 0; i < 10; ++i) {
    boost::system::error_code ignored_error;
  boost::asio::write(socket, boost::asio::buffer("Hello, World!"), ignored_error);
}

我现在的问题是一次发送所有 10 行。但我想要 10 条单独的消息。我认为boost::asio::ip::tcp::no_delay 会有所帮助。但事实并非如此。

我测试的nodejs客户端看起来:

import * as net from 'net';

const client = new net.Socket();

client.connect(3232, 'localhost', () => {
    console.log('Connected');
});

client.on('data', data => {
    console.log(`Received: ${data}`);
});


client.on('close', () => {
    console.log('Connection closed');
});

client.on('data', ...) 在这里只调用过一次。

有谁知道写完后如何“刷新”?

或者这是nodejs客户端实现的错误?

【问题讨论】:

  • '我的问题是现在所有 10 行都同时发送。'不,您的问题是您不了解 TCP 的八位字节(字节)流性质。如果您想要离散消息,(应用程序协议单元)。超过一个字节,您需要在 TCP 之上使用适当的协议。

标签: c++ tcp boost-asio flush


【解决方案1】:

TCP 在概念上是一种流协议,没有数据报的概念(与 UDP 不同)。一旦数据被添加到 TCP 缓冲区,它将以尽可能少的 IP 数据包发送。同样在另一端,所有传入的数据包边界信息都丢失了。所有传入的数据都合并到一个缓冲区中。因此,如果您需要框架,则需要在应用程序级别实现它。

【讨论】:

  • 我已经多次看到这个答案,但我仍然无法让它发挥作用。在我杀死客户端之前,服务器不会读取消息,所以我认为需要一些刷新
  • 可能需要禁用 Nagle 算法 (TCP_NODELAY)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-08
  • 1970-01-01
  • 2012-06-06
  • 1970-01-01
  • 2020-02-15
  • 1970-01-01
  • 2018-05-02
相关资源
最近更新 更多