代码之家  ›  专栏  ›  技术社区  ›  Elan

为什么订阅了多播组的UDP套接字正在接收非多播消息?

  •  0
  • Elan  · 技术社区  · 17 年前

    在客户端,我执行以下操作:

    1. 设置监听套接字以订阅和接收服务器发起的多播消息。
    2. 设置一个接收套接字,以接收服务器对客户端多播的响应

    一切正常,除了两个接收套接字最终都会收到服务器对客户端的(非多播)响应。我不清楚这是否是预期的行为。我可以把两个接收插座减少到一个吗?#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);
    

    // 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);
    
    4 回复  |  直到 17 年前
        1
  •  3
  •   caf    17 年前

        2
  •  2
  •   Steve-o    16 年前
    receiveSocket.Bind(new IPEndPoint(IPAddress.Any, 50000));
    

    您的接收套接字绑定到任何地址,这意味着它们将接收单播、广播和多播流量。您可以绑定到接口地址以仅接收单播流量,也可以仅绑定到多播组以仅接收多播流量。

    发送UDP数据报时,您可以指定目标地址,可以是多播或单播。因此,您可以将服务器和客户端代码分别减少到一个套接字。

        3
  •  0
  •   Brian Agnew    17 年前

    相同 IP多播地址(例如239.1.1.1)。目前,您似乎已经为客户端和服务器各提供了一个地址,如果/当您引入新客户端时会发生什么?

        4
  •  0
  •   Indy9000    17 年前

    更好的选择是使用服务发现协议,如 Bonjour Avahi