1
votes

I'm fairly new with UDP sockets with most of my socket experience being with TCP.

I'm using C# to create a UDP socket, bind it and then continually listen for packets from an IP. However, when the client sends a packet, the socket throws an exception: "An existing connection was forcibly closed by the remote host".

This is how I create the UDP socket:

Socket UDPSocket = new Socket(SocketType.Dgram, ProtocolType.Udp); //Create UDP socket
UDPSocket.Bind(new IPEndPoint(IPAddress.Any, 1338)); //Bind port 1338 from any IP

After creating the socket, I asynchronously receive data:

UDPSocket.BeginReceiveFrom(newClient.bufferu, 0, AbstractServerClient.BUFFER_SIZE, 0, ref newClient.remoteEndpoint,new AsyncCallback(ReceiveCallbackUDP), newClient);

newClient.remoteEndpoint an endpoint from a TCP socket, so the UDP is effectively receiving packets from the same IP that the TCP is connected to. Assume the rest of the paramaters are valid (They work fine on TCP).

The ReceiveCallbackUDP method looks like this:

public void ReceiveCallbackUDP(IAsyncResult ar)
{
    AbstractServerClient client = (AbstractServerClient)ar.AsyncState;
    int bytesRead = UDPSocket.EndReceive(ar);

    if (bytesRead > 0)
    {
        Bitstream data = new Bitstream(client.bufferu, 12);
        int bytesProcessed = 12;
        while (bytesProcessed < bytesRead)
        {
            ushort messageLength = data.ReadUInt16(); //Read the message length
            byte messageID = data.ReadByte(); //Read the message ID
            // Logger.Log("Received message ID: " + messageID.ToString() + " (Size: " + messageLength + " bytes)");
            bytesProcessed += messageLength + sizeof(UInt16);
            client.GetPacketHandler(messageID).HandlePacket(data); //Process the message
            bytesProcessed += 12;
            data.Seek(bytesProcessed); //Seek to the next message
        }
    }
    UDPSocket.BeginReceiveFrom(client.bufferu, 0, AbstractServerClient.BUFFER_SIZE, 0, ref client.remoteEndpoint, new AsyncCallback(ReceiveCallbackUDP), client);
}

This function calls EndReceive() on the socket to read the data, and processes it, and called BeginReceiveFrom to wait for more data (asynchronously). The exception is thrown on the line int bytesRead = UDPSocket.EndReceive(ar);

Why is this happening? To my understanding, UDP is a connectionless socket so the exception "An existing connection was closed" doesn't make sense. Am I doing something wrong here?

1
You are probably running into the same issue as that mentioned here: stackoverflow.com/questions/7201862/…Manoj Pandey

1 Answers

0
votes

In BeginReceiveFrom your remoteEP should indentify the socket that is listening, mostly the same endpoint that you have used for the Bind.

And in your callback method ReceiveCallbackUDP you should call EndReceiveFrom, as this is the corresponding Method to BeginReceiveFrom:

EndPoint tempRemoteEP = (EndPoint)client.remoteEndpoint;
int bytesRead = UDPSocket.EndReceiveFrom(ar, ref tempRemoteEP);

See the Example in http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.beginreceivefrom.aspx, where tempRemoteEP passed to BeginReceiveFrom is the same Endpoint as sender passed to Bind.