【问题标题】:Opening multiple ports using Boost Asio libraries使用 Boost Asio 库打开多个端口
【发布时间】:2012-02-23 19:14:24
【问题描述】:

我是 Boost Asio 库的新手,我的要求是构建一个服务器,它应该异步监听 600 个不同的端口(TCP 通信)。有人可以建议我使用 Boost Asio 实现这一目标的聪明方法。我尝试使用 Boost Asio 文档中提供的回显服务器示例,但不太了解 boost::asio::io_service io_service;

using namespace std; // For atoi.
for(long port=50000;port<=50600;port++)
{
    server s(io_service, port);
    io_service.run();
}

有人可以解释一下吗?

【问题讨论】:

  • '我的要求是建立一个服务器,它应该监听 600 个不同的端口' - 你确定这是你想要做的吗?
  • 是的 Martin,它与模拟设备有关,我有 600 个模拟设备,因此我需要为每个设备单独连接。
  • @user1229153 您可以在单个端口上接受与单个服务器的任意数量的连接。
  • @spencercw,但它会帮助我在打开所有连接的情况下进行异步通信吗?如果您能提供任何方便的链接,我将不胜感激。
  • @user1229153 绝对。阻塞 I/O 通常是一个坏主意 (IMO),当然,当您有 600 个同时连接时,您希望异步执行此操作。查看chat examples。您可以忽略与聊天相关的内容,但服务器管理多个会话的概念非常有效。

标签: c++ boost boost-asio


【解决方案1】:

io_service 负责处理分配给它的所有 I/O;您不需要为每个端口创建一个单独的端口。对于您要执行的操作,您需要创建 600 个单独的服务器实例,然后调用 io_service.run()

vector<shared_ptr<server> > servers;
for (uint16_t port = 50000; port != 50600; ++port)
{
    servers.push_back(shared_ptr<server>(new server(io_service, port)));
}
io_service.run();

【讨论】:

  • 谢谢Spencercw,我还有一个问题,如何以二进制格式打印接收到的数据?我将它接收到一个字符缓冲区中,因此 _itoa 失败了。
  • @user1229153 使用 iostream 很容易做到这一点。抱歉格式错误;我不能在 cmets 中执行多行操作。unsigned char buf[] = { '\xab', '\xcd', '\xef' }; cout &lt;&lt; hex &lt;&lt; setfill('0'); for (size_t i = 0; i != sizeof(buf); ++i) { cout &lt;&lt; setw(2) &lt;&lt; static_cast&lt;unsigned&gt;(buf[i]); } cout &lt;&lt; "\n"; 这将打印出 abcdef
  • 非常感谢@spencercw,我明白你在这里做什么。我不知道我的问题是否有意义,在我的程序服务器中,服务器从客户端接收数据,并且它在 char* 变量中接收它,当我尝试打印它时,它是一些 ascii 值。我想看看我的客户到底发送了什么信息。如 Asio 示例 socket_.async_read_some(boost::asio::buffer(data_, max_length)
  • @user1229153 您可以使用我发布的代码打印出您的char * 缓冲区。您需要先将每个字节转换为 unsigned char,然后再将其转换为 unsigned,否则将无法正确打印。即static_cast&lt;unsigned&gt;(static_cast&lt;unsigned char&gt;(buf[i]))。如果您愿意,也可以直接在调试器中查看内存。
  • 有没有办法让boost库返回调用函数只读取一次数据?我的意思是——在这个例子中boost.org/doc/libs/1_48_0/doc/html/boost_asio/example/echo/…,我可以在读取客户端发送的数据后返回 io_service.run() 执行一些功能并返回监听模式吗?而不是坐在忙碌的循环中听取客户的意见?有什么建议可以实现这一目标?
【解决方案2】:

尝试一些类似的东西

boost::asio::ip::tcp::socket socket(io_service);

socket.async_connect(endpoint, connectHandler);

socket 变量是单个套接字的实例,对async_connect 的调用会设置到endpoint 定义的位置的异步连接。您可以以类似的方式对socket 执行异步读取和写入操作,只需确保io_service.run() 在某个线程中运行,否则异步调用(和相关的回调)将不会被执行...

【讨论】:

  • 感谢回复,对不起,我没完全理解,你要我在服务器类中添加这个吗?
  • 是的,尽管回想起来,您可能希望实例化一个侦听器而不是尝试async_connect,因为这是一个服务器而不是客户端。假设您已经在 server 对象中实例化了一个侦听器,@spencercw 提出的解决方案可能更接近您的需要。
猜你喜欢
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-20
  • 2011-05-15
  • 1970-01-01
  • 2022-01-15
相关资源
最近更新 更多