每个套接字地址只有一次使用(proto / ip / port)

时间:2016-01-17 20:44:40

标签: c# sockets networking

美好的一天

的信息:

主题:多播

首先,我找到了解决方案,但我不明白为什么这是解决方案。

**范围:**(删除任何混乱/不必要的代码)

new_socket()
{
    //SND_LOCAL_IP = 10.0.0.30 - local network adapter's IP
    //SND_MCAST_PORT = 80 port used to broadcast Multicast Packets 

    //_SND_LOCAL_EP = new IPEndPoint(SND_LOCAL_IP, SND_MCAST_PORT);  <problem>                                       
    _SND_LOCAL_EP = new IPEndPoint(SND_LOCAL_IP, 0);                 <fixed>    
}

init_socket()
{
    _SND_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    _SND_Socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(_SND_MCAST_IP, _SND_LOCAL_IP));
    _SND_Socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.ReuseAddress, true);
    _SND_Socket.ExclusiveAddressUse = false;
    _SND_Socket.Bind(_SND_LOCAL_EP);      <<< ====== PROBLEM LINE=====
}

问题:

我的侦听器在form_load事件上单独运行一个Thread,因此它以与我的SND_Socket相同的方式初始化,但是将SND_Socket.Bind()端口更改为0允许我接收这些多播数据包。

由于def MSDN,添加ExclusiveAddress不应该缓解这个问题(因为接收和发送套接字以相同的方式初始化)。

  

如果Socket只允许一个套接字绑定到特定端口,则为true;否则,错误。对于Windows Server 2003和Windows XP Service Pack 2,默认值为true;对于所有其他版本,默认值为false。

并且在备注中,这已得到确认:

  

如果ExclusiveAddressUse为false,则多个套接字可以使用Bind方法绑定到特定端口;但是只有一个套接字可以对发送到端口的网络流量执行操作。如果多个套接字尝试使用Bind(EndPoint)方法绑定到特定端口,则具有更具体IP地址的套接字将处理发送到该端口的网络流量。

     

如果ExclusiveAddressUse为true,则首次使用Bind方法尝试绑定到特定端口,无论Internet协议(IP)地址如何,都将成功;所有后续使用Bind方法尝试绑定到该端口都将失败,直到原始绑定套接字被销毁。

     

必须在调用Bind之前设置此属性;否则将抛出InvalidOperationException。

为什么执行

  

Socket.ExclusiveAddress = false

不允许SND_Socket将此IP和端口侦听为“Listener_Socket”,此外为什么在RCV_Socket.Bind()中将端口设置为0可以解决此问题?

1 个答案:

答案 0 :(得分:4)

如果没有一个好的Minimal, Complete, and Verifiable Example,就不可能确切地知道你具体是什么问题,更不用说知道原因是什么。缺乏这一点,一些观点/评论与所述问题有关:

  1. ExclusiveAddressUse属性不会影响它所设置的套接字,而是影响该套接字后绑定的任何其他套接字。它可以防止任何其他套接字使用相同的端口号,即它可以通过ReuseAddress套接字选项执行此操作。
  2. ReuseAddress套接字选项 会影响其设置的套接字。这是允许套接字绑定到同一端口上的同一个适配器上的某个其他套接字已被绑定的内容。
  3. 通常不会同时使用这两个选项。您希望套接字协作,其中一个允许另一个使用相同的端口号,或者您希望禁止任何其他套接字使用相同的端口号。
  4. 绑定到端口0在某些情况下可以缓解在滥用地址排他性选项时可能发生的问题。由于问题不完整,我无法推断出您遇到的具体问题。但是绑定到端口0会导致套接字选择一个唯一的端口号,这当然会避免端口号冲突的任何问题。
  5. 除此之外,我在您的代码中看到的最大问题是您在致电Bind()之前尝试加入多播组。您应该以相反的方式执行此操作,即绑定套接字,然后然后加入多播组。
  6. 最有可能的是,您根本不应该使用ReuseAddress。您的套接字应具有唯一的端口号。 可能使用ExclusiveAddressUse作为预防措施,以确保在某些代码尝试将套接字绑定到已在使用的端口时出现异常。
  7. 我建议您按照the documentation page for the MulticastOption Class上MSDN上的示例,按密切开头。使用该代码后,您可以调整代码以适应您的特定需求。