为什么我需要在套接字上定义两次端点才能开始接收数据

本文关键字:端点 两次 开始 数据 套接字 定义 为什么 | 更新日期: 2023-09-27 18:21:51

我正在做一个项目,如果我想从设备接收SNMP陷阱(如果你想知道的话)。我使用了这个例子中的代码http://www.snmpsharpnet.com/?page_id=117我正试图从中建立一个barebones函数。但我不明白的是:

public bool InitializeReceiver()
{
        _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        EndPoint localEP = new IPEndPoint(IPAddress.Parse(ip), port);
        _socket.Bind(localEP);
    if (!RegisterReceiveOperation())
        return false;
    return true;
}

在这一行,我设置了设备的IpAddress和我想监听的端口,对吗?

EndPoint localEP = new IPEndPoint(IPAddress.Parse(ip), port);

然后在这里

public bool RegisterReceiveOperation()
{
    _peerIP = new IPEndPoint(IPAddress.Any, 0);
    EndPoint ep = (EndPoint)_peerIP;
    _inbuffer = new byte[64 * 1024];
    _socket.BeginReceiveFrom(_inbuffer, 0, 64 * 1024,
        SocketFlags.None, ref ep, new AsyncCallback(ReceiveCallback), _socket);
    return true;
}

什么是peerIP?我是否将其设置为与以前相同的IPAddress和端口?还是我就这样算了?

此外,需要注意的是,该网站的原始代码可以正常工作,我正确地接收陷阱,但在我的应用程序中,我希望连接得到更好的管理,我不能一直测试它。所以,如果有人能弄清楚那些不同的IPEndPoint是什么,那就太好了。

注意2:我删除了我在这里发布的修改后的代码中的很多try-and-catch块,以及其他我认为与这个问题无关的东西。

为什么我需要在套接字上定义两次端点才能开始接收数据

Socket通信总是涉及两个端点:本地端点(您侦听的端点)和远程端点(您从中接收或连接到的端点)。对于像UDP这样的面向无连接的协议,不需要绑定到本地端点。但是,如果您没有显式绑定到特定的本地端点,则提供程序将自动选择任何可用的端点。实际上,当您使用本地端点连接到远程主机,而不是侦听传入连接时,面向连接的协议也是如此。

ReceiveFrom方法族中的端点是您希望数据来自的端点。如果您愿意接受来自任何端点的数据,那么您应该指定IPAddress.Any和零端口号。如果您提供了一个更具体的端点,那么来自其他源的任何数据都将被静默丢弃,并且只接收来自指定端点的数据。请注意,该参数是通过引用传递的。方法返回后,变量将包含接收数据的实际端点。

因此,总结一下:您需要定义两次端点,因为您同时指定了本地端点和远程端点。此外,如果您事先知道这些信息并希望它永远不会改变(有点不太可能),那么您可以很好地在BeginReceiveFrom方法中指定远程设备的IP地址和端口号。

取自Socket.Bind(..)MSDN页面

@备注secion:

在调用Bind之前,您必须首先创建本地IPEndPoint打算从该IPEndPoint通信数据

现在,这部分摘自Socket.BeginReceiveFrom(..)MSDN页面

@参数"remoteEP":

表示数据源的端点

来自备注:

在调用BeginReceiveFrom之前,必须使用bind方法将套接字显式绑定到本地终结点,否则BeginReceiveFrom将引发SocketException。