客户端断开连接,但服务器看不到它

时间:2018-01-28 11:51:22

标签: c# .net sockets exception tcp

所以当我在客户端断开连接时出现问题时,我正在制作Tcp服务器。异常被抛出,但看起来服务器看不到它。并且它不会从列表中删除断开连接的客户端。这是代码:

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

            }
            else
            {
                SplitRead[PL] += BytesRead[PL];
                while (true)
                {
                    if (SplitRead[PL] < 4)
                    {
                        break;
                    }
                    int num = BitConverter.ToInt16(readBuffer[PL], 2);
                    if (SplitRead[PL] < num)
                    {
                        break;
                    }
                    if (!Tlist.ContainsKey(PL))
                        Tlist.Add(PL, new List<RecvData>());
                    {
                        Tlist[PL].Add(new RecvData(readBuffer[PL], num));
                    }
                    int index = 0;
                    for (int i = num; i < SplitRead[PL]; i++)
                    {
                        readBuffer[PL][index] = readBuffer[PL][i];
                        index++;
                    }
                    SplitRead[PL] -= num;
                }
            }
        }
        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))
            {
                clients.Remove(PL);
            }
            else
            {
                System.Console.WriteLine(x.ToString());
            }
        }
    }

当客户端关闭程序或被任务管理器

杀死时,会发生这种情况

这是使用方法Read的地方。

    private void HandleClient(object client)
    {

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

            try
            {
                while ((true))
                {
                    {
                        if (!ClientAuthComplete.ContainsKey(tcpClient))
                            ClientAuthComplete.Add(tcpClient, false);
                        if (!readBuffer.ContainsKey(tcpClient))
                            readBuffer.Add(tcpClient, new byte[102400]);
                        if (!SplitRead.ContainsKey(tcpClient))
                            SplitRead.Add(tcpClient, 0);
                        if (!BytesRead.ContainsKey(tcpClient))
                            BytesRead.Add(tcpClient, 0);
                        if (!Tlist.ContainsKey(tcpClient))
                            Tlist.Add(tcpClient, new List<RecvData>());

                        try
                        {

                            IAsyncResult result = ns.BeginRead(readBuffer[tcpClient], SplitRead[tcpClient], 30000, null, null);
                            Read(result, tcpClient);
                        }
                        catch (SocketException ex)
                        {
                            if ((ex.Message.Contains("Client") && ex.Message.Contains("Disconnected")) || ex is SocketException)
                            {
                                throw;
                            }
                        }
                        try
                        {
                            if (Tlist.ContainsKey(tcpClient))
                            {
                                if (Tlist[tcpClient].Count >= 1)
                                {
                                    for (int i = 0; i < Tlist[tcpClient].Count; i++)
                                    {
                                        ReceiveData(Tlist[tcpClient][i].Buffer, Tlist[tcpClient][i].Len, tcpClient);
                                    }
                                    Tlist.Clear();
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                        }
                    }
                }
            }
            catch (SocketException ex)
            {

                if (((ex.Message.Contains("Client") && ex.Message.Contains("Disconnected"))) || ex is SocketException )
                {
                    clients.Remove(tcpClient);

                    readBuffer.Remove(tcpClient);
                    SplitRead.Remove(tcpClient);
                    BytesRead.Remove(tcpClient);
                    Tlist.Remove(tcpClient);
                    threads[tcpClient].Abort();
                    threads.Remove(tcpClient);
                    ClientAuthComplete.Remove(tcpClient);
                    RemoveClientFromList(tcpClient);
                }
                else
                {
                    System.Console.WriteLine(ex.ToString());
                }
            }
        }
    }

以下是TcpListener初始化

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

这是接受TcpClient

的方法
    private void ListenForClients()
    {

        listener.Start();

        while (true)
        {
            System.Console.Title = "Black3D 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 (!readBuffer.ContainsKey(client))
                    readBuffer.Add(client, new byte[102400]);
                if (!SplitRead.ContainsKey(client))
                    SplitRead.Add(client, 0);
                if (!BytesRead.ContainsKey(client))
                    BytesRead.Add(client, 0);
                if (!Tlist.ContainsKey(client))
                    Tlist.Add(client, new List<RecvData>());
                if (!threads.ContainsKey(client))
                    threads.Add(client, new Thread(new ParameterizedThreadStart(HandleClient)));
                //if (threads.ContainsKey(client))
                {
                    threads[client].Start(client);
                }
                counter++;

            }


        }
    }

1 个答案:

答案 0 :(得分:0)

threads[tcpClient].Abort();放置试用指令之前

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