C # UDP Server Asynchronous Multiple Clients | SocketException on client disconnect

I worked on a program on a socket server in C # (I was inspired by this post ), and my problem is that when a client throws an exception "An existing connection was forcibly closed by the remote host " appears when EndReceiveFrom () is called and returns 0 , client client ref becomes a customer who usually closes. I do not understand why my DoReceiveFrom () function is called if there is nothing to read. I probably missed something. What's wrong?

The problem appears there:

int dataLen = this.serverSocket.EndReceiveFrom(iar, ref clientEP);

Full source code:

class UDPServer
{
    private Socket serverSocket = null;
    private List<EndPoint> clientList = new List<EndPoint>();
    private List<Tuple<EndPoint, byte[]>> dataList = new List<Tuple<EndPoint, byte[]>>();
    private byte[] byteData = new byte[1024];
    private int port = 4242;

    public List<Tuple<EndPoint, byte[]>> DataList
    {
        private set { this.dataList = value; }
        get { return (this.dataList); }
    }

    public UDPServer(int port)
    {
        this.port = port;
    }

    public void Start()
    {
        this.serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        this.serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        this.serverSocket.Bind(new IPEndPoint(IPAddress.Any, this.port));
        EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
        this.serverSocket.BeginReceiveFrom(this.byteData, 0, this.byteData.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, newClientEP);
    }

    private void DoReceiveFrom(IAsyncResult iar)
    {
        try
        {
            EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
            int dataLen = this.serverSocket.EndReceiveFrom(iar, ref clientEP);
            byte[] data = new byte[dataLen];
            Array.Copy(this.byteData, data, dataLen);

            if (!this.clientList.Any(client => client.Equals(clientEP)))
                this.clientList.Add(clientEP);

            EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
            this.serverSocket.BeginReceiveFrom(this.byteData, 0, this.byteData.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, newClientEP);

            DataList.Add(Tuple.Create(clientEP, data));
        }
        catch (ObjectDisposedException)
        {
        }
    }

    public void SendTo(byte[] data, EndPoint clientEP)
    {
        try
        {
            this.serverSocket.SendTo(data, clientEP);
        }
        catch (System.Net.Sockets.SocketException)
        {
            this.clientList.Remove(clientEP);
        }
    }

    public void SendToAll(byte[] data)
    {
        foreach (var client in this.clientList)
        {
            this.SendTo(data, client);
        }
    }

    public void Stop()
    {
        this.serverSocket.Close();
        this.serverSocket = null;

        this.dataList.Clear();
        this.clientList.Clear();
    }
}

An exception:

An existing connection was forcibly closed by the remote host

Update: (netcat) , , SendTo(), List, , .

+4
1

, .

Async: BeginDo() AsyncCallback ( DoReceiveFrom). - BeginDo() .

EndDo(), , : , BeginDo ( ), - , . , .

Async.

, ,

  • , ,
  • , BeginReceiveFrom, EndReceiveFrom. , BeginReceiveFrom EndReceiveFrom. , , , .

try-catch EndReceiveFrom.

UPDATE

private void DoReceiveFrom(IAsyncResult iar)
{
    try
    {
        EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
        int dataLen = 0;
        byte[] data = null;
        try
        {
            dataLen = this.serverSocket.EndReceiveFrom(iar, ref clientEP);
            data = new byte[dataLen];
            Array.Copy(this.byteData, data, dataLen);
        }
        catch(Exception e)
        {
        }
        finally
        {
            EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
            this.serverSocket.BeginReceiveFrom(this.byteData, 0, this.byteData.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, newClientEP);
        }

        if (!this.clientList.Any(client => client.Equals(clientEP)))
            this.clientList.Add(clientEP);

        DataList.Add(Tuple.Create(clientEP, data));
    }
    catch (ObjectDisposedException)
    {
    }
}
0

Source: https://habr.com/ru/post/1540119/


All Articles