Ghi*_*ita 5 c++ networking boost boost-asio
我在我的udp服务器中使用相同的套接字以便从某些端口上的客户端接收数据,然后在处理请求后使用ip :: ud :: socket :: async_send_to响应客户端
接收也与async_receive_from异步完成.套接字使用相同的ioService(毕竟它是相同的套接字)文档没有明确说明是否可以在同一个udp套接字从客户端A接收数据报(以异步方式)并可能将另一个数据报发送到客户端B(异步)我怀疑这可能导致问题.我最终使用相同的套接字进行回复,因为在回复另一个客户端时,我无法将另一个套接字绑定到同一个服务器端口.
如何将另一个套接字绑定到同一个服务器端口?
编辑.我尝试将第二个udp套接字绑定到同一个UDP端口:
socket(ioService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port))
Run Code Online (Sandbox Code Playgroud)
当我第一次这样做(绑定服务器"接收"套接字)时没关系,但是第二次尝试创建另一个套接字,就像它在bind上报告错误一样(asio抛出异常)
Tan*_*ury 14
可以从一个远程端点同时接收UDP套接字并发送到不同的远程端点.但是,根据Boost.Asio Threads和Boost.Asio文档,对单个对象进行并发调用通常是不安全的.
因此,这是安全的:
thread_1 | thread_2 --------------------------------------+--------------------------------------- socket.async_receive_from( ... ); | socket.async_send_to( ... ); |
这是安全的:
thread_1 | thread_2
--------------------------------------+---------------------------------------
socket.async_receive_from( ... ); |
| socket.async_send_to( ... );
但这被指定为不安全:
thread_1 | thread_2
--------------------------------------+---------------------------------------
socket.async_receive_from( ... ); | socket.async_send_to( ... );
|
请注意,某些功能(例如boost::asio::async_read,组合操作)具有其他线程安全限制.
如果满足以下任一条件,则不需要进行其他同步,因为流将隐式同步:
io_service::run()仅从单个线程调用.async_receive_from并且async_send_to仅在同一个异步操作链中调用.例如,ReadHandler传递给async_receive_from调用async_send_to,WriteHandler传递给async_send_to调用async_receive_from.
void read()
{
socket.async_receive_from( ..., handle_read ); --.
} |
.-----------------------------------------------'
| .----------------------------------------.
V V |
void handle_read( ... ) |
{ |
socket.async_send_to( ..., handle_write ); --. |
} | |
.-------------------------------------------' |
| |
V |
void handle_write( ... ) |
{ |
socket.async_receive_from( ..., handle_read ); --'
}
Run Code Online (Sandbox Code Playgroud)另一方面,如果有多个线程可能对套接字进行并发调用,则需要进行同步.考虑通过boost :: asio :: io_service :: strand调用函数和处理程序,或使用其他同步机制(如Boost.Thread的互斥锁)来执行同步.
除线程安全外,还必须考虑对象生命周期的管理.如果服务器需要同时处理多个请求,然后小心的所有权buffer和endpoint每个请求- >流程- >响应链.根据Per async_receive_from的文档,调用者保留缓冲区和端点的所有权.因此,通过boost :: shared_ptr管理对象的生命周期可能更容易.否则,如果链足够快以至于不需要并发链,那么它简化了管理,允许每个请求使用相同的缓冲区和端点.
最后,socket_base::reuse_address该类允许将套接字绑定到已在使用的地址.但是,我不认为这是一个适用的解决方案,因为它通常用于:
TIME_WAIT状态.| 归档时间: |
|
| 查看次数: |
10820 次 |
| 最近记录: |