Search code examples
c#tcpbindingudptcp-port

You must call the Bind method before performing this operation => No, I don't


I'm working on two applications (a server one and a client one), both communicating with each other via TCP port 7447.

The server application is already running and is connected on the mentioned port:

Prompt>netstat -aon | findstr "7447"
  UDP    0.0.0.0:7447           *:*                                    41316

Prompt>tasklist /FI "PID eq 41316"

Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
       MyServer.exe          41316 Console                    1     71.308 K

In the client application, I'm trying to receive information from the server application, as follows:

private void Receive()
{
    BaseTelegram telegram = null;
    IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, this._listenPort);
    try
    {
        Byte[] receivedBytes = this._udpClient.Receive(ref endpoint);

The mentioned _udpClient has following properties:

Properties screenshot

I also know it has passed via this source code:

public UdpConnection(System.Net.Sockets.UdpClient udpClient, Int32 listenPort)
{
    this._listenPort = listenPort;
    this._udpClient = udpClient;
}

I know for a fact that the client application is running at customer's site, but on my PC, I get the following exception:

System.InvalidOperationException: 'You must call the Bind method before performing this operation.'

I'm not interested in how I should adapt the source code in order to make it work (as the code is working at customer's premises, it should work on my PC too), I'd like to know which configuration I need to alter in order to make this code work.


Solution

  • If you do not specify a port parameter when constructing a UdpClient, then the client will not be bound to a local port, and you cannot call the Receive method. For example:

    this._udpClient = new UdpClient();
    var endpoint = new IPEndPoint(IPAddress.Any, this._listenPort);
    // You must call the Bind method before performing this operation.
    this._udpClient.Receive(ref endpoint);
    

    This behaviour is mentioned in the document:

    Before calling ReceiveFrom, you must explicitly bind the Socket to a local endpoint using the Bind method. If you do not, ReceiveFrom will throw a SocketException.

    The direct solution is to specify a port parameter when constructing the UdpClient (0 is also possible):

    this._udpClient = new UdpClient(0);
    

    Another implicit solution is to call the Send method before calling the Receive method, that's because the underlying service provider will assign the most appropriate local network address and port number.

    this._udpClient = new UdpClient();
    this._udpClient.Send(data, dataLength, remoteEP); // This turns out to be 
                                                      // the final solution.
    ....
    this._udpClient.Receive(ref endpoint);