C# - 要关闭NetworkStream,请调用stream.Close或socket.Shutdown?

时间:2011-02-18 22:38:35

标签: c# sockets stream networkstream

我想知道是否有人知道处理使用Socket对象和NetworkStream对象的类的最佳方法?有问题的类有一个NetworkStream实例和一个用于创建NetworkStream的Socket实例。

this.socket = new Socket(
                           AddressFamily.InterNetwork,
                           SocketType.Stream,
                           ProtocolType.Tcp)
                        {
                            ReceiveBufferSize = 65536,
                            SendBufferSize = 150
                        };

this.socket.Connect(
                        new IPEndPoint(                                                                   
                              IPAddress.Parse(
                                          Properties.Settings.Default.MpsServer2),
                                          Properties.Settings.Default.MpsPort2));

this.stream = new NetworkStream(
                         this.socket, true);

在我的Dispose方法中,我应该这样做吗?

this.stream.Close();
this.socket.Shutdown(SocketShutdown.Both);
this.socket.Close();

所有这些都是必要的还是过度杀伤?

3 个答案:

答案 0 :(得分:2)

Socket不会处置关联的NetworkStream。我确定了reflector。 (一种分析.NET dll和.NET库的工具。很棒的工具。你必须在月底之前下载免费版本才能完全商业化。)

但是,根据the MDSN documentation和反射器,流将关闭套接字,但前提是它拥有套接字的所有权。您可以将其设置为重载构造函数中的第二个参数。

在任何情况下都必须致电Shutdown,因为flushes the data。如果不这样做,您可能会丢失数据。

答案 1 :(得分:1)

SocketStream都实施IDisposable,因此您只需在每个对象上调用.Dispose()即可。 Dispose方法应该处理关闭和处理所需的其他操作。

this.stream.Dispose(); 
this.socket.Dispose(); 

例如,这是来自流类的反汇编Dispose方法:

public void Dispose()
{
    this.Close();
}

答案 2 :(得分:1)

根据MSDN中的文档,调用stream.Close()“关闭当前流并释放与当前流关联的所有资源(如套接字和文件句柄)。”,它告诉我stream.Close()也配置插座。你仍然需要调用socket.Shutdown()。

无论如何,恕我直言最安全的方式是使用“使用”,它让你在安全的网站上:)

using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
                        {
                            ReceiveBufferSize = 65536,
                            SendBufferSize = 150
                        };) {
  socket.Connect(
    new IPEndPoint(
      IPAddress.Parse(
        Properties.Settings.Default.MpsServer2), Properties.Settings.Default.MpsPort2));

  using (var stream = new NetworkStream(socket, true) {
    // do something with the stream here
  }

  socket.Shutdown(SocketShutdown.Both);
}