【问题标题】:Setting ASIO no_delay option设置 ASIO no_delay 选项
【发布时间】:2016-11-04 02:12:10
【问题描述】:

我在设置 asio 套接字上的 no_delay 选项时遇到问题。以下代码运行良好,除了延迟。我的服务器仅在 5000 毫秒过期后才收到消息。

#include <boost/asio.hpp>
#include <boost/thread.hpp>
using namespace boost::asio;
struct Client
{
   io_service svc;
   ip::tcp::socket sock;

   Client() : svc(), sock(svc)
   {
       ip::tcp::resolver resolver(svc);
       ip::tcp::resolver::iterator endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query("127.0.0.1", "32323"));
       connect(sock, endpoint);
   }

   void send(std::string const& message) {
       sock.send(buffer(message));
   }
};

int main()
{
   Client client;

   client.send("hello world\n");
   client.send("bye world\n");

   boost::this_thread::sleep_for(boost::chrono::milliseconds(5000));
}

尝试添加延迟时,我有几个选择:
1) 连接前添加选项:

Client() : svc(), sock(svc)
{
   ip::tcp::resolver resolver(svc);
   ip::tcp::resolver::iterator endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query("127.0.0.1", "32323"));

   sock.set_option(ip::tcp::no_delay(true));
   connect(sock, endpoint);
}

但是这会抛出set_option: Bad file descriptor

2) 连接后添加选项:

Client() : svc(), sock(svc)
{
   ip::tcp::resolver resolver(svc);
   ip::tcp::resolver::iterator endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query("127.0.0.1", "32323"));

   connect(sock, endpoint);
   sock.set_option(ip::tcp::no_delay(true));
}

但是在这种情况下,该选项无效,我仍然看到延迟。根据boost::asio with no_delay not possible? ,我需要在打开套接字之后但在连接套接字之前设置选项。所以我试过这个:

Client() : svc(), sock(svc)
{
     ip::tcp::endpoint endpoint( ip::address::from_string("127.0.0.1"), 32323);
     sock.open(ip::tcp::v4());
     sock.set_option(ip::tcp::no_delay(true));
     sock.connect(endpoint);
}

但是,我仍然没有看到任何效果。如何设置此选项?

编辑:我可能没有在服务器端正确设置选项。这是完整的服务器代码:

#include <boost/asio.hpp>
#include <iostream>

int main() {
    boost::asio::io_service        io_service;
    boost::asio::ip::tcp::acceptor acceptor(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 32323));
    boost::asio::ip::tcp::socket   socket(io_service);

    acceptor.accept(socket);
    socket.set_option(boost::asio::ip::tcp::no_delay(true));

    boost::asio::streambuf sb;
    boost::system::error_code ec;
    while (boost::asio::read(socket, sb, ec)) {
        std::cout << "received:\n" << &sb;
    }
}

【问题讨论】:

  • 服务器是否也设置了no_delay 选项?
  • 感谢您的回复。我没有在服务器端设置它。我想我现在正在设置它,但仍然看不到效果。我已经编辑了原始帖子以包含服务器代码。

标签: tcp boost-asio


【解决方案1】:

客户端正确设置了ip::tcp::no_delay 选项。但是,观察到的延迟不是此选项的结果。相反,它是服务器尝试读取的数据多于客户端发送的数据的结果,当客户端在休眠 5000ms 后退出时,服务器的读取操作完成并出现错误。

服务器启动的read() 操作将在读取streambuf.max_size() 字节或发生错误时完成。 streambuf 的最大大小默认为std::numeric_limits&lt;std::size_t&gt;::max(),可以在其constructor 中进行配置。在这种情况下,服务器尝试读取std::numeric_limits&lt;std::size_t&gt;::max()字节,但客户端只发送了22个字节,休眠了5000ms,然后关闭了套接字。当服务器观察到连接已关闭时,read() 操作完成,读取了 22 个字节,错误代码为boost::asio::error::eof

【讨论】:

  • 这很有意义。我只是在阅读Boost's chat client example 并试图弄清楚他们为什么在数据的第一个字节中发送缓冲区大小。这解释了它。感谢您的信息。
猜你喜欢
  • 2015-08-21
  • 1970-01-01
  • 2015-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
相关资源
最近更新 更多