每个套接字地址(proto/ip/port)仅使用一种 [英] Only one use of each socket address (proto/ip/port)

查看:232
本文介绍了每个套接字地址(proto/ip/port)仅使用一种的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好!

信息:

主题:组播

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

First off, I have found the solution but I do not understand why this is the solution.

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

**Scope : ** (removing any cluttering/unnecessary code)

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事件上分别在线程上运行,因此它的初始化方式与我的SND_Socket相同,但是将SND_Socket.Bind()端口更改为0允许我接收这些多播数据包.

My listener runs on a Thread seperately, on a form_load event, thus it initializes in the same way as my SND_Socket does, however changing the SND_Socket.Bind() port to 0 allows me to recieve these Multicast packets.

As by the def MSDN, adding the ExclusiveAddress should not alleviate this problem (since the recieve and send sockets are initialized in the same way).

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

true if the Socket allows only one socket to bind to a specific port; otherwise, false. The default is true for Windows Server 2003 and Windows XP Service Pack 2, and false for all other versions.

进一步,在备注"中已确认:

and further on, in Remarks this is confirmed:

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

If ExclusiveAddressUse is false, multiple sockets can use the Bind method to bind to a specific port; however only one of the sockets can perform operations on the network traffic sent to the port. If more than one socket attempts to use the Bind(EndPoint) method to bind to a particular port, then the one with the more specific IP address will handle the network traffic sent to that port.

如果ExclusiveAddressUse为true,则无论Internet协议(IP)地址如何,第一次使用Bind方法尝试绑定到特定端口都将成功;在原始绑定套接字被销毁之前,所有随后使用Bind方法尝试绑定到该端口的操作都将失败.

If ExclusiveAddressUse is true, the first use of the Bind method to attempt to bind to a particular port, regardless of Internet Protocol (IP) address, will succeed; all subsequent uses of the Bind method to attempt to bind to that port will fail until the original bound socket is destroyed.

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

This property must be set before Bind is called; otherwise an InvalidOperationException will be thrown.

为什么

Socket.ExclusiveAddress = false

Socket.ExclusiveAddress = false

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

not allow the SND_Socket to listen on this IP and port as "Listener_Socket", furthermore why does setting port to 0 in the RCV_Socket.Bind() solve this problem?

推荐答案

没有一个好的最小,完整和可验证的示例无法确定您到底遇到了什么问题,也没关系确定原因.缺少这些意见/评论与陈述的问题有关:

Without a good Minimal, Complete, and Verifiable Example it's impossible to know for sure what problem you're even having specifically, never mind know for sure what the cause would be. Lacking that, some observations/comments related to the question as stated:

  1. ExclusiveAddressUse属性不会影响设置该套接字的套接字,而是会影响该套接字之后绑定的任何其他套接字.这样可以防止任何其他套接字使用相同的端口号,即通过ReuseAddress套接字选项可以使用的端口号.
  2. ReuseAddress套接字选项确实影响设置该套接字的套接字.这是允许套接字绑定到同一适配器上的其他套接字已绑定到的同一端口的原因.
  3. 通常不会同时使用这两个选项.您要么希望套接字配合使用,要么让一个套接字允许另一个套接字重用相同的端口号,要么您想要禁止任何其他套接字使用相同的端口号.
  4. 绑定到端口0在某些情况下可以缓解滥用地址专有性选项时可能发生的问题.对于不完整的问题,我无法推断您遇到的具体问题.但是绑定到端口0会导致套接字选择唯一的端口号,这当然可以避免任何与端口号冲突的问题.
  5. 除此之外,我在代码中看到的最大问题是,您在调用Bind()之前尝试加入多播组.您应该采用另一种方法,即绑定套接字,然后然后加入多播组.
  6. 最有可能的是,您根本不应该使用ReuseAddress.您的套接字应具有唯一的端口号.您可以 使用ExclusiveAddressUse作为预防措施,以确保如果某些代码确实尝试将套接字绑定到已在使用的端口上,则会得到异常.
  1. The ExclusiveAddressUse property affects not the socket on which it's set, but any other socket bound after that socket. It prevents any other socket from using the same port number, i.e. which it would otherwise be able to do through the ReuseAddress socket option.
  2. The ReuseAddress socket option does affect the socket on which it's set. It's what allows a socket to bind to the same port that some other socket on the same adapter had already been bound.
  3. One would typically not use both of those options at the same time. Either you want the sockets to cooperate, where one allows the other to reuse the same port number, or you want to prohibit any other socket from using the same port number.
  4. Binding to port 0 can in some cases alleviate issues that might otherwise occur when misusing the address-exclusivity options. With the incomplete question, I cannot infer what specific problem you are having. But binding to port 0 causes the socket to select a unique port number, which will of course avoid any problems with port number conflicts.
  5. Other than that, the biggest issue I see in your code is that you are attempting to join the multicast group before you call Bind(). You should be doing it the other way around, i.e. bind the socket, and then join the multicast group.
  6. Most likely, you should not be using ReuseAddress at all. Your sockets should have unique port numbers. You may use ExclusiveAddressUse, as a preventative measure to ensure you get an exception if some code does try to bind a socket to a port that's already in use.

我建议您紧接着 从MSDN上的

I recommend that you start by closely following the example found on MSDN on the documentation page for the MulticastOption Class. Once you have a working example using that code, then you can adjust the code to suit your specific needs.

这篇关于每个套接字地址(proto/ip/port)仅使用一种的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆