我什么时候需要处理(服务器-客户端)对象

本文关键字:客户端 对象 服务器 什么时候 处理 | 更新日期: 2023-09-27 18:28:23

在服务器(多)客户端应用程序[TCP]中。我在服务器中接受的每个客户端都使用Socket、NetworkStream、StreamReader和StreamWriter。。所以我有几个问题:

  • 当我想关闭与客户端的连接时,是否必须将它们全部处理掉?
  • 如果客户端释放与服务器连接的套接字。。我是否也必须在服务器端处理该套接字,或者它会自动关闭?
  • 在我的代码中:
     Thread thAccept = new Thread(acceptClient);
     Thread thJob;
     private void acceptClient()
        {
            while (true)
            {
                Socket client = server.Accept();
                Console.WriteLine(client.RemoteEndPoint+" has connected");
                StreamReader reader = new StreamReader(new NetworkStream(client));
                //is it ok to create an instance NetworkStream like this or i will have to dispose it later?
                thJob = new Thread(Job);
                thJob.Start(reader);
            }
        }
     private void Job(object o)
        {
            StreamReader reader = (Socket)o;
            try
            {
                string cmd = null;
                while ((cmd = reader.ReadLine()) != null)
                {
                  //(BLA BLA..)
                }
            }
            catch
            {
                Console.WriteLine("Disconnected by catch");  
            }
            finally
            { 
                Console.WriteLine("Finally Done.");
                reader.Dispose();
            }
        }
    

    该代码可以处理所有(需要处理的)对象吗?

  • 我什么时候需要处理(服务器-客户端)对象

    这不是重复的。

    您的代码与链接的重复代码不同,因为在您的代码中,IDisposable被传递给另一个线程。

    一般规则是,如果你创建了一个实现IDisposable的对象,那么当你完成它时,你负责在它上调用Dispose。如果可能,这应该在using块中完成,以确保Dispose总是被调用。在您的情况下,直到退出另一个线程,您的代码才与对象一起完成。在该线程中,您可以正确地调用finally块中的Dispose

    如果你在NetworkStream上调用Dispose,那么它也会关闭StreamReader,这将违背你的目的。我怀疑如果你在Socket上打电话给Dispose也是一样的。因此,您的代码是正确的。

    客户端的对象与服务器端的对象没有任何关系,除非通过TCP/IP。客户端可以在其套接字上调用Dispose这一事实并不意味着服务器必须在其套接字调用Dispose。但是,一旦服务器完成了从套接字读取数据,并且连接关闭,服务器端套接字就应该是Disposed。我不确定,但我相信当StreamReader被释放时,底层的NetworkStream将被释放,它应该在创建流的套接字上调用Dispose

    您的代码很好,除了一些不相关的问题:您不需要将cmd设置为null,因为您将在下一条语句中设置该值。此外,您不应该像那样使用空的catch块。您不知道抛出了什么异常,但无论如何都会忽略它,甚至不会记录或显示异常。至少,你应该做

        catch (Exception ex)
        {
            Console.WriteLine("Disconnected by exception " + ex.ToString());   
        } 
        finally 
        {  
            Console.WriteLine("Finally Done."); 
            reader.Dispose(); 
        }