概要:サーバーとクライアントをセットアップしました。どちらも UDP を使用して互いの検出を試みます。サーバーが起動すると、サーバーは稼働中であることを示すマルチキャスト メッセージ (239.1.1.1) を送信します。クライアントが起動すると、クライアントは自分が生きていることを示すマルチキャスト メッセージ (239.1.1.2) を送信します。サーバーとクライアントの両方が、互いのマルチキャスト メッセージにサブスクライブして、送信を受信します。このようにして、どちらのアプリケーション (サーバーまたはクライアント) が最初に起動するかに関係なく、どちらか一方にその存在が通知されます。
クライアント側では、次のことを行います。
- サーバーから発信されたマルチキャスト メッセージをサブスクライブして受信するために、リッスン ソケットを設定します。
以下の #3 に従って、クライアントのマルチキャスト メッセージに対するサーバー応答を受信する受信ソケットをセットアップします。- クライアントが実行しているマルチキャスト メッセージを (サーバーが受信して応答するように) 送信します。
- #3 で送信されたクライアントのマルチキャスト メッセージに対するサーバーの応答を受信します。
質問:両方の受信ソケットがサーバーの (非マルチキャスト) 応答をクライアントに取得することを除いて、すべて正常に動作しています。これが予想される動作かどうかはわかりません。2 つの受信ソケットを 1 つに減らすことはできますか? #1 はサーバーのマルチキャストにサブスクライブし、#2 は同じポートでサーバーからの直接送信 (サーバーからの非マルチキャスト メッセージ) をリッスンするだけです。2 番目の受信ソケットを安全に取り外すことができますか?
以下のソース コードを参照してください (コード表示を簡略化するために例外処理を削除しました)。
クライアントコード:
// 1. Set up a socket and asynchronously listen for server startup multicasts.
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
listenSocket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, 1);
listenSocket.Bind(new IPEndPoint(IPAddress.Any, 50000));
listenSocket.SetSocketOption(SocketOptionLevel.IP,SocketOptionName.AddMembership,
new MulticastOption(IPAddress.Parse("239.1.1.1")));
EndPoint clientEndPoint = new IPEndPoint(0, 0);
listenSocket.BeginReceiveFrom(receiveBuffer, 0, receiveBuffer.Length,
SocketFlags.None, ref clientEndPoint,
new AsyncCallback(OnServerMessageReceived), (object)this);
// 2. Set up socket to receive the server's response to client's multicast.
Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
receiveSocket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, 1);
receiveSocket.Bind(new IPEndPoint(IPAddress.Any, 50000));
receiveSocket.ReceiveTimeout = 3000; // Timeout after 3 seconds.
// 3. Send a multicast message for server to respond to.
Socket sendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
EndPoint multicastEndPoint = new IPEndPoint(IPAddress.Parse("239.1.1.2"), 50000);
sendSocket.SendTo(packet, packet.Length, SocketFlags.None, multicastEndPoint);
// 4. Wait for server to respond to the multicast message (timeout = 3 seconds).
byte[] receiveBuff = new byte[2048];
EndPoint serverEndPoint = new IPEndPoint(0, 0);
int bytesRead = receiveSocket.ReceiveFrom(receiveBuff, ref serverEndPoint);
サーバーコード:
// Receive multicast message sent from client (in asynchronous callback method).
EndPoint clientEndPoint = new IPEndPoint(0, 0);
int bytesRead = listenSocket.EndReceiveFrom(asyncResult, ref clientEndPoint);
// Send response back to the client (change port to 50000).
EndPoint destination = new IPEndPoint((clientEndPoint as IPEndPoint).Address,
50000);
Socket responseSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
responseSocket.SendTo(response, response.Length, SocketFlags.None, destination);