Search code examples
c#.netsocketsexceptiontcp

Client disconnected, but server don't see it


so i was making a Tcp Server, when i got a problem while a client is disconnecting. Exception is being throwed, but it looks like that server don't see it. And it don't remove the disconnected client from list. Here is code:

    public void Read(IAsyncResult ar, TcpClient PL)
    {
        try
        {
            {
                BytesRead[PL] = PL.GetStream().EndRead(ar);
            }
            if (BytesRead[PL] < 1)
            {
                throw new SocketException();

            }
            else
            {
                while (true)
                {
                    packets++; break;
                }
            }
        }
        catch (Exception x)
        {
            if ((x.Message.Contains("Client") && x.Message.Contains("Disconnected")) || x is SocketException || x is EndOfStreamException || x is IOException)  //|| x.InnerException.GetType() == typeof(IOException))
            {
               throw;
            }
            else
            {
                System.Console.WriteLine(x.ToString());
            }
        }
    }

It occurs when client closes program or when it's killed by task manager

Here is where method Read has been used.

    private void HandleClient(object client)
    {

        TcpClient tcpClient = (TcpClient)client;
        NetworkStream ns = tcpClient.GetStream();
        while (true)
        {

            try
            {
                while ((true))
                {
                    {
                        

                        try
                        {

                            
                        }
                        catch (SocketException ex)
                        {
                            if ((ex.Message.Contains("Client") && ex.Message.Contains("Disconnected")) || ex is SocketException)
                            {
                                throw;
                            }
                        }
                        try
                        {
         
                            {
                                
                            }
                        }
                        catch (Exception ex)
                        {
                        }
                    }
                }
            }
            catch (SocketException ex)
            {
            
                if (((ex.Message.Contains("Client") && ex.Message.Contains("Disconnected"))) || ex is SocketException )
                {
                    clients.Remove(tcpClient);
                }
                else
                {
                    System.Console.WriteLine(ex.ToString());
                }
            }
        }
    }

Here is the TcpListener Initialization

    public void Server1()
    {
        timer = new Timer(new TimerCallback(MultipleCheck), null, 0, 500);
        listener = new TcpListener(IPAddress.Parse("25.75.22.56"), 29339);
        listenThread = new Thread(new ThreadStart(ListenForClients));
        listenThread.Start();
    }

And here is method where it accepts the TcpClient

    private void ListenForClients()
    {

        listener.Start();

        while (true)
        {
            System.Console.Title = "Server : " + clients.Count.ToString();
            if (!LineStarted)
            {
                System.Console.WriteLine("Server started on port 29339");
                LineStarted = true;
            }
            System.Console.WriteLine("Connection Request");
            TcpClient client =  listener.AcceptTcpClient();
            if (client.Connected)
            {
                clients.Add(client);
                System.Console.WriteLine("New Client Connected");
                
                //if (threads.ContainsKey(client))
                {
                    threads[client].Start(client);
                }
                counter++;
                
            }

            
        }
    }

Solution

  • Before the threads[tcpClient].Abort(); put try instruction

    try
    {
    //Removing Client from list and notifying connected users about disconnected 
    //client from list
    }
    catch
    {
    }
    //And after Abort the thread to avoid the exception of thread aborting being
    //thrown too early
    threads[tcpClient].Abort();
    threads.Remove(tcpClient);