8

基盤となるNetworkStream.Write()を使用して、サーバーにデータを送信するTcpClientオブジェクトがあります。そのため、私は持っています:

TcpClient server = new TcpClient(serverName, 50001);

/* ... */

NetworkStream stream = server.GetStream();

これで、ボタンを押すと接続が閉じます。接続を閉じる正しい方法は何ですか?MSDNのドキュメントによると、TcpClientを(.Close()を使用して)閉じると、実際にはソケットは閉じられず、TcpClientリソースのみが閉じられます(少なくとも私がドキュメントを理解した方法です)。

では、次のコードを実行すると、接続が正しく閉じられますか?

stream.Close();
server.Close();

これで十分ですか、それとも最初に(何らかの方法で)ストリーム(またはサーバー)を閉じることができるかどうかを確認する必要があります(接続が半分開いている場合など)...

さらに、NetworkStream.Close()MSDNのドキュメントには、リソース(ソケットも含む)が解放されると記載されているため、ストリームを閉じるだけで十分であり、それ以降はTcpClientを使用できなくなります。

正しいアプローチは何ですか?

4

3 に答える 3

6

ドキュメントが言うように:

このメソッドを呼び出すと、最終的に関連付けられたソケットが閉じられ、データが作成された場合にデータの送受信に使用される関連付けられたNetworkStreamも閉じられます。

だからserver.Close();十分でしょう。

ただし、最初にNetworkStreamを閉じても問題はありません。

ちなみに、たまたま1つのメソッドでのみTcpClientを使用している場合は、例外がスローされた場合などでも、(と同等の)がusing( )確実に呼び出されるようにステートメントでラップしてください。Dispose()Close()

于 2009-11-20T09:20:23.807 に答える
3

TCP接続をソケットに関連付けます。

一般に、手順は次のようになります。1.データの送信を終了します2.SocketShutdown.Sendパラメーターを使用してSocket.Shutdownを呼び出します3.0を返すか、例外で失敗するまで受信をループします4. Close()を呼び出します

これは、C#に非常によく似た擬似コードの小さなサンプルです:)

void CloseConnection(Socket socket)
{
   socket.Send(/*last data of the connection*/);
   socket.Shutdown(SocketShutdown.Send);

   try
   {
      int read = 0;
      while( (read = socket.Receive(/*application data buffers*/)) > 0 )
      {}
   }
   catch
   {
      //ignore
   }
   socket.Close();
}

最初と3番目のステップをスキップすると、データが失われる可能性があります。

TCPソケットを閉じる方法から引用

于 2009-11-20T09:33:13.220 に答える
0

ストリームを閉じてからサーバーを閉じるのは正しいことです。これにより、ドキュメントに記載されているように、時間の経過とともにすべてのソケットが正常に閉じられるはずです。ただし、いくつかの頭を掻くバグは、時間の経過とともに重要な教訓を私に教えてくれました。

フラッシュすることを忘れないでください!

stream.Flush();
stream.Close();
server.Close();

他の方法で送信したと思われるデータが失われることがよくあります。これは、ストリームを閉じるときにストリームが空で非アクティブであることを確認するのにも役立ちます。

于 2009-11-20T09:24:17.793 に答える