2016-09-09 21 views
1

こんにちは、ありがとうございました。 今回はTcpClientについて質問したいと思います。 私はサーバープログラムを持っており、クライアントプログラムを作成しています。 このクライアントはTcpClientを使用します。これは、新しいクライアントTcpClient:もう一度閉じると再接続するにはどうすればいいですか?

clientSocket=new TcpClient(); 

を作成することによって開始する(ちなみに、することができます。この原因の例外?私はのtry-catchの内側にそれを置くが、それが本当に必要であるかどうかはわからない念のため)後に、とにかく 私はループに入り、このループ内で私は、サーバーに

clientSocket.Connect("xx.xx.xx.xx",port); 

を接続それから私は

clientStream=clientSocket.GetStream(); 

でNetworkStreamを作成し、サーバーthrouからのデータを待って開始しますgh読む。私はこれがブロックされているので、私はReadTimeOut(例えば1秒)を設定することも知っています。

とにかく、とても良いです。 後でサーバーから何も受信しなければ、何かを送信しようとします。これは言うために3回起こって続けた場合、私は、サーバーへの接続を閉じて再接続したい再び

(予告サーバが何らかの形でのエラーの他の種類の原因となる原因は、ダウンしているときはまったく違う問題があることをクライアント - おそらく私はそれについて後でお尋ねします)

どうすればいいですか?

if(clientSocket.Connected) 
      { 
       Console.WriteLine("Closing the socket"); 
       clientSocket.Close(); 
      } 

ソケットを閉じます。 ループが終了したので、私は最初に戻り、サーバーに接続しようとします。

clientSocket.Connect("xx.xx.xx.xx",port); 

しかし、これはそう私の質問は、私は閉じて、再びサーバーに再接続するにはどうすればよいでエラー(実際には未処理の例外が)「に配置されたオブジェクトにアクセスできません」

の原因?任意の助け再び

おかげ

+0

感謝。私はタグを付け加えた。それは大丈夫ですか? (コメントに新しい行を挿入するにはどうすればいいですか...私がEnterを押すと、コメントを追加します。ctrl-enter、shift-enterを試しても動作しません... – KansaiRobot

+1

ありがとう!段落やキャリッジリターンをサポートしていません。それらは常に1つのテキストブロックです。段落ではなくコメントです:-)複数の段落を必要とするようなコメントが必要な場合はほとんどありません。 –

+0

捕捉している例外を明示的に知っていて、意味のある処理ができる場合にのみ、 'try' /' catch'ブロックにコードを入れてください。例外をキャッチするのはアンチパターンです。 https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/ – Enigmativity

答えて

2

TcpClientインスタンスは一度だけ接続するために使用することができます。新しいTcpClientをインスタンス化するだけで、閉じたものを再オープンするのではなく、単純にインスタンス化することができます。

+0

ありがとうございます。これはそうですか?だから私は新しいものをインスタンス化する必要があります.... C + +のいくつかのコードでは、私は彼らがソケットを使用しているだけで、彼らは(彼らは非同期を使用している)新しいソケットを "作成"します。しかし、TcpClientには「作成」がありませんので、ちょうど新しいものが正しく使用されるはずです。ところで、私は別の関連する質問があり、私はこの問題を修正した後に投稿します。 :)でも、新しいTcpClientをインスタンス化すると例外が発生する可能性がありますか? – KansaiRobot

+0

ところで、私はそれをtry-catchの中に置くべきでしょうか? – KansaiRobot

+1

それは働いているようです:)ところで、私はTcpClientを閉じると、私はすべてのリソースが処分されていると思いますか?ガベージコレクタがそれを取得するのでしょうか?私はインスタンス化の新しい反復が実行されるたびに物事を残しておきたくありません..... – KansaiRobot

1

the other answerで説明したように、TcpClientオブジェクトは1回しか接続できません。サーバーに再接続する場合は、新しいTcpClientオブジェクトを作成し、Connect()を再度呼び出す必要があります。あなたは再びTcpClientオブジェクトを使用しようとしているのいかなる意図を持っている場合

  1. 最初の、そして最も重要な、あなたは、例えば、ReceiveTimeoutを使用しないでください:あなたはあなたの質問で明らかに誤解の数を持っている、と述べた

    いくつかのデータをサーバーに送信します。タイムアウト期間が終了すると、基本となるソケットは使用できなくなります。

    サーバーがデータを送信していないときに定期的にサーバーにデータを送信する場合は、非同期I/O(学習曲線にもかかわらず)を使用し、通常のタイマーオブジェクトサーバーからデータを受信して​​からの経過時間を記録します。

  2. TcpClientコンストラクタは確かに例外をスローできます。少なくともへの試みがnewになると、参照型オブジェクトはOutOfMemoryExceptionを投げ、TcpClientの場合は最終的に失敗するネイティブソケットハンドルを作成しようとします。

    すべてのI/Oオブジェクトおよびメソッドは例外をスローすることができますが、例外的に例外をキャッチするだけで正常に処理することができます。したがって、コードにtry/catchブロックを追加する前に、コードでデータが破損していないことを確実にする例外が発生した場合、何をしたいのかを決定し、正しく動作させてください。 OutOfMemoryExceptionを正常に処理することはできません(いずれの場合もnewのすべての用途を保護することは実際的ではありません)。しかし、確かにSocketExceptionをキャッチしてコンストラクタによってスローすることができます。その例外がスローされた場合は、すぐにTcpClientの作成と使用を中止し、ソケットの作成を妨げていた問題を修正しようとするエラーを報告してください。
  3. サーバーがデータを送信していて、受信できないと思われる場合は、接続を閉じて再試行しても状況が改善されることはありません。これはサーバーに負荷をかけるだけで、応答しなくなる可能性がさらに高まります。同様に、同じデータを繰り返し送信します。あなたの要求はに一度お待ちください。サーバーからの応答が実用的である限り待ち、希望の時間内に応答がない場合は、そのエラーをユーザーに報告して、次に何をすべきかを決定させます。

    の場合はReceiveTimeoutプロパティを使用できます。時間内に応答が得られない場合は、接続を中止しても問題ありません。これは問題ありません。
+0

アドバイスをいただきありがとうございます。私はあなたがReadTimeoutプロパティについて話していると思いますか? – KansaiRobot

+0

@KansaiRobot: 'TcpClient'の関連プロパティは' ReceiveTimeout'です。しかし、これは 'NetworkStream.ReadTimeout'に相当します。どちらも最終的に 'SocketOptionName.ReceiveTimeout'で' Socket.SetSocketOption() 'を呼び出します。 –

0

非常にシンプル:

client.Close(); 
client = new TcpClient(); 
client.Connect(host, port); 
関連する問題