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

时间:2012-03-21 04:34:49

标签: c# stream client-server dispose idisposable

在服务器 - (多)客户端应用程序[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();
            }
        }
    

    是处理所有(需要处置)对象的代码吗?

  • 1 个答案:

    答案 0 :(得分:0)

    这不重复。

    您的代码与链接的副本不同,因为在您的代码中,IDisposable会移交给另一个帖子。

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

    如果您在Dispose上调用NetworkStream,那么它也会关闭StreamReader,这会破坏您的目的。我怀疑如果你在Dispose上调用了Socket,那将是同样的事情。因此,您的代码按原样正确。

    客户端上的对象与服务器端的对象没有关系,除非通过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(); 
        }