概述:我已经建立了一个服务器和一个客户端,在这两个服务器都尝试使用UDP发现彼此。当服务器启动时,它会发送一条多播消息(239.1.1.1),表明它处于活动状态。当客户端启动时,它发送一个多播消息(239.1.1.2),表明它处于活动状态。服务器和客户端都订阅对方的多播消息以接收其传输。这样,无论哪个应用程序(服务器或客户端)首先启动,其中一个或另一个将被通知它们的存在。为什么UDP套接字订阅一个多播组正在拾取一个非多播消息?
在客户端我做到以下几点:
- 建立一个监听套接字订阅和接收服务器发起的多播消息。
- 设置一个接收套接字来接收服务器对客户端组播的响应。
- 发送客户端正在运行的转发消息(用于服务器接收并响应)。
- 接收服务器对#3中发送的客户端多播消息的响应。
问:一切工作正常,除了两个接收插座最终得到服务器的(非组播)响应客户端。我不清楚这是否是预期的行为。我可以将两个接收套件减少到一个吗? #1订阅了服务器的组播,#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);
Server代码:
// 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);
在多播环境中,为什么服务器甚至需要知道客户端? – MyItchyChin 2009-07-21 16:01:21
我使用多播的唯一原因是在所有客户端和单个服务器之间建立发现。发现完成后,我切换到TCP/IP(WCF netTcpBinding),然后服务器可以将消息发送到客户端。客户端也可以向服务器发送某些客户端事件的通知。 – Elan 2009-07-22 19:25:35
你已经提到了不同的(组播)客户端地址。你是说客户1将有一个地址,客户2将有另一个? – 2010-02-02 08:20:42