如何使用boost :: asio断开UDP套接字

时间:2012-12-19 04:16:59

标签: udp boost-asio

结合来自boost docsmanual for connect function的信息我认为 asio :: udp :: socket :: connect 函数用于设置数据报所在的地址默认发送,以及接收数据报的唯一地址。

这很好用,但手册还说明我应该能够解散关联(断开连接),这就是我遇到的问题。即我希望套接字再次开始从任何地址接收数据包。

进一步在手册中写道:

Connectionless sockets may dissolve the association by connecting to an
address with the sa_family member of sockaddr set to AF_UNSPEC.

我试过这段代码:

asio::udp::endpoint unspecified_endpoint;
assert(unspecified_endpoint.address().is_unspecified()); // OK
socket.connect(unspecified_endpoint);

但这没有帮助。


编辑:通过从boost :: asio页面获取clientserver示例来创建测试用例。在客户端代码中,我已将传出端口号从随机更改为5192:

udp::socket s(io_service, udp::endpoint(udp::v4(), 5192));

我在服务器代码中更改了 server 功能:

void server(boost::asio::io_service& io_service, short port)
{
  udp::socket sock(io_service, udp::endpoint(udp::v4(), port));

#define CASE 3

#if CASE == 1
  sock.connect(udp::endpoint());
#elif CASE == 2
  sock.connect(udp::endpoint(ip::address::from_string("127.0.0.1"), 5193));
  sock.connect(udp::endpoint());
#elif CASE == 3
  sock.connect(udp::endpoint(ip::address::from_string("192.168.1.3"), 5192));
  sock.connect(udp::endpoint());
#endif

  for (;;)
  {
    char data[max_length];
    udp::endpoint sender_endpoint;
    size_t length = sock.receive_from(
    boost::asio::buffer(data, max_length), sender_endpoint);
    sock.send_to(boost::asio::buffer(data, length), sender_endpoint);
  }
}

案例1和案例2似乎有效,但在案例3中,客户不会收到回复。完整的来源可以找到here

1 个答案:

答案 0 :(得分:2)

正如评论中所述,对sock.connect(udp::endpoint());的调用转换为connect(6, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, 16) = 0,与connect的{​​{1}}不同,并且不会完全断开UDP套接字(它似乎只重置对等端口号)。

我认为有一种方法可以用boost asio实现你想要的东西,但是你可以使用本机POSIX调用来断开套接字,比如

AF_UNSPEC

调试说明:使用struct sockaddr unspec_addr = { AF_UNSPEC }; ::connect(sock.native_handle(), &unspec_addr, sizeof(unspec_addr)); 运行程序,然后使用strace列出UDP套接字。