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

时间:2014-09-15 12:01:05

标签: c# sockets snmp

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

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和catch块,以及其他我认为与此问题无关的内容。

2 个答案:

答案 0 :(得分:3)

取自Socket.Bind(..) MSDN page

@Remarks secion:

  

在致电Bind之前,您必须首先创建本地IPEndPoint 打算来传播数据。

现在,这部分取自Socket.BeginReceiveFrom(..) MSDN page

@Parameter'remoteEP':

  

EndPoint,代表数据来源。

来自备注:

  

在调用BeginReceiveFrom之前,必须使用Bind方法将Socket显式绑定到本地端点,否则BeginReceiveFrom将抛出SocketException。

答案 1 :(得分:2)

套接字通信总是涉及两个端点:本地端点(您监听的端点)和远程端点(您从中接收或连接的端点)。使用无连接的协议(如UDP),无需绑定到本地端点。但是,如果您未明确绑定到特定的本地端点,则提供程序将自动选择任何可用的端点。嗯,实际上,当您使用本地端点连接到远程主机而不是侦听传入连接时,面向连接的协议也是如此。

ReceiveFrom系列方法中的端点是您期望数据来自的端点。如果您愿意接受来自任何端点的数据,则应指定IPAddress.Any和端口号为零。如果提供更具体的端点,则会静默丢弃来自其他源的任何数据,并且仅接收来自指定端点的数据。请注意,参数通过引用传递。方法返回时,变量将包含从中接收数据的实际端点。

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