0

我有两个几乎相同的测试程序(A 和 B),它们使用相同的 boost asio UDP 异步代码。

这是接听电话:

_mSocket.async_receive_from(
            boost::asio::buffer(_mRecvBuffer), _mReceiveEndpoint,
            boost::bind(&UdpConnection::handle_receive, this,_mReceiveEndpoint,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
// _mReceiveEndpoint is known and good. the buffer is good too.

// 这里是处理程序

void handle_receive(const udp::endpoint recvFromEP, const boost::system::error_code& error,std::size_t  bytesRecv/*bytes_transferred*/)
{
    boost::shared_ptr<std::string> message(new std::string(_mRecvBuffer.c_array(),bytesRecv));
    if (!error) 
      {
      doSomeThingGood();
      } 
else {
        cerr << "UDP Recv error : " << error << endl;
    }
}

所以这就是发生的事情,都在本地主机上。

如果我先启动程序“A”,然后程序“B”,“A”会给出 UDP Recv 错误:服务器:10061。程序“A”继续发送正常,“B”接收正常。

您可以在上面的句子中交换“A”和“B”,它仍然是正确的。

如果我通过再次调用 mSocket.async_receive_from 尝试重置错误的读取条件,则会收到错误 10054。

我在网上查过这些错误......不是很有帮助。

任何人都知道这些是什么意思,如果发生这种情况,我如何在程序中恢复?有没有办法重置插座?

健全性检查....两个程序都可以在只有两个端口的环回上运行吗?A 发送 = 20000,A 接收 = 20001 B 发送 = 20001,B 接收 = 20000

TL;DR 看起来好像我在发送之前尝试收听,我收到一个错误并且我无法从中恢复。如果我在发送后听,我很好。

- 编辑 - 看来 McAfee 主机入侵防护对我做了一些讨厌的事情......如果我在 VS2010 中调试,我会卡在他们的 DLL 中。

谢谢

4

2 回答 2

2

在我的接收处理程序中,我没有再次调用 _mSocket.async_receive_from() ......我只是打印了错误并退出了。

愚蠢的错误,只是在这里发帖以防它帮助其他人。

同样对于具有不同分辨率的类似问题: _mSocket.set_option(boost::asio::socket_base::reuse_address(true));

如果您有多个听众,这会有所帮助。

于 2013-03-26T16:29:40.450 回答
0

一些消息来源解释说您应该在 Windows 上使用 SO_REUSEADDR。但是没有人提到可以在绑定和绑定套接字的情况下接收 UDP 消息。下面的代码将套接字绑定到本地listen_endpoint,这是必不可少的,因为没有它您可以并且仍然会收到您的UDP消息,但默认情况下您将拥有端口的独占所有权。

但是如果你在socket上(或者使用TCP的时候在acceptor上)设置reuse_address(true),然后再绑定socket,就会让多个应用,或者你自己应用的多个实例再做一次,每个人都会收到消息。

// Create the socket so that multiple may be bound to the same address.
boost::asio::ip::udp::endpoint listen_endpoint(
    listen_address, multicast_port);

// == important part ==
socket_.open(listen_endpoint.protocol());
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
socket_.bind(listen_endpoint);
// == important part ==

boost::array<char, 2000> recvBuffer;
socket_.async_receive_from(boost::asio::buffer(recvBuffer), m_remote_endpoint,
        boost::bind(&SocketReader::ReceiveUDPMessage, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)

来源: http: //www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/multicast/receiver.cpp

于 2014-07-22T19:11:35.470 回答