socketssnmpsharpnet

Why do i need to define a endpoint on a socket twice to start receiving data?


I am doing a project were i want to receive SNMP traps from a device (just if you wanted to know). I am trying to just set up a barebones function from this. But what i dont understand is here:

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;
}

At this line i set the IpAddress of the device and the port i want to listen too right?

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

And then here

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;
}

What is the _peerIP? Do i set it to the same IPAddress and port as before? Or do i leave it like that?

Also as a note the original code from the site works and i receive the traps correctly but in my application i want the connection to be more managed and i cant really test it all the time. So if someone could clear up what those difrent IPEndPoint's are would be great.

Note 2: I removed a lot of try and catch blocks from my modified code that i posted here and other stuff that i dont think have anything to do with this question.


Solution

  • Socket communications always involves two endpoints: a local endpoint (the one you listen on), and a remote endpoint (the one you receive from or connect to). With connectionless oriented protocols like UDP, there is no need to bind to a local endpoint. However, if you do not explicitly bind to a specific local endpoint, the provider will automatically choose any that is available. Well, actually the same is true for connection oriented protocols as well when you use the local endpoint to connect to a remote host, instead of listening for incoming connections.

    The endpoint in the ReceiveFrom family of methods is the endpoint you expect the data to come from. If you are willing to accept data from any endpoint, then you should specify IPAddress.Any and a port number of zero. If you supply a more specific endpoint, then any data from other sources is silently discarded, and only data from the specified endpoint is received. Note that the parameter is passed by reference. Upon method return, the variable will contain the actual endpoint from which data was received.

    So, summing up: you need to define an endpoint twice because you are specifying both the local, and the remote endpoints. Plus, you can very well specify the remote device's IP address and port number in the BeginReceiveFrom method if you know this information beforehand and expect it to never change (kind of unlikely).