0

同じブースト asio UDP 非同期コードを使用する、ほぼ同一の 2 つのテスト プログラム (A & B) があります。

受信呼び出しは次のとおりです。

_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;
    }
}

では、すべて localhost で何が起こるかを説明します。

プログラム 'A' を最初に起動すると、プログラム 'B', 'A' で UDP Recv エラー : server:10061 が発生します。プログラム「A」は問題なく送信を続け、「B」は問題なく受信します。

上記の文で「A」と「B」を入れ替えることができますが、それはそのままです。

mSocket.async_receive_from を再度呼び出して読み取り不良状態をリセットしようとすると、エラー 10054 が発生します。

これらのエラーを Web で調べましたが、あまり役に立ちませんでした。

これらが何を意味するのか、この状態が発生した場合にプログラム内でどのように回復できるかについて、誰か考えがありますか? ソケットをリセットする方法はありますか?

健全性チェック.... 両方のプログラムが 2 つのポートのみのループバックで動作できますか? 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 メッセージを受信することができますが、デフォルトでは、ポートの排他的な所有権を持っています。

ただし、reuse_address(true) をソケット (または TCP を使用する場合はアクセプター) に設定し、後でソケットをバインドすると、複数のアプリケーションまたは独自のアプリケーションの複数のインスタンスが再度それを実行できるようになり、全員がすべてを受信します。メッセージ。

// 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 に答える