2017-05-18 12 views
0

私は最近、Socketを使用して複数のクライアントアプリケーションを開発しました。ソケットサーバに接続されている各ソケットクライアントを廃棄する

サーバは接続されたクライアントを追跡する必要はありません。接続を要求するクライアントがある場合、サーバーはそれを受け入れます。任意のクライアントからの要求がある場合(データを取得する場合)、サーバーはそのクライアントに応答します。

/// <summary> 
/// Callback when server accepts a new incoming connection. 
/// </summary> 
/// <param name="result">Incoming connection result object.</param> 
private void AcceptedCallback(IAsyncResult result) 
{ 
    try 
    { 
     Socket clientSocket = _socket.EndAccept(result); // Asynchronously accepts an incoming connection attempt 

     if (clientSocket.Connected) // Check if the client is in 'Connected' state 
     { 
     StateObject state = new StateObject(); 
     state.clientSocket = clientSocket; 
     clientSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, // Start listening to client request 
            ReceiveCallback, state); 
     } 
     else 
     { 
      clientSocket.Close(); // Terminate that client's connection 
     Log.writeLog("TCPServer(AcceptedCallback)" 
        , "Client's status is not connected."); 
     } 
    } 
    catch (Exception ex) 
    { 
     Log.writeLog("TCPServer(AcceptedCallback)" 
       , ex.Message); 
     clientSocket.Close(); 
    } 
    finally 
    { 
     Accept(); // Start to accept new connection request 
    } 
} 

私はこの件について3つの質問があります。各に対して

  1. BeginReceive私は、新たに接続されたクライアントのために作成し、私のサーバーアプリケーションはそれを保持するために、新しいスレッド/オブジェクトを作成しませんクライアント?

  2. クライアントが接続された後、ネットワークケーブルがクライアント側でプルオフされてプラグインされると、クライアントは再びサーバーに接続します。このシナリオの場合、これはサーバー上の新しい接続と見なされます何度も何度も発生しますが、私のサーバープログラムはクラッシュしますか?

  3. したがって、サーバーに接続されている各クライアントを追跡し、その状態を追跡してClose/Disposeを呼び出す必要がありますか?

は、これまでのところ、シナリオ2のための私のテストでは、私のサーバープログラムで検出された異常はありませんが、私は、誰かが私のためにこれを明確に役立つだろう願っています。ありがとうございました。

答えて

0
  1. いいえ、スレッドのプールからIO完了スレッドを使用します。
  2. いいえ、これに対応するようにコードすることができ、コード化する必要があります。 OSが検出できるクライアント側で何かが発生した場合、TCP fin/ackをサーバに送信します。これにより、BeginXXXメソッドはまだ非同期コールバックメソッドを待っているはずです。そこから、EndXXXメソッドの呼び出しで例外がスローされるか、ソケットから読み取られるゼロバイトが返されます。
  3. これは、それらを適切に処分することを続けることによって何を意味するかによって異なります。エラーを検出した場合は、それらを破棄することを意味します。いいえ、EndXXXメソッドにクリーンアップコードを入れることができます。サーバーをシャットダウンした場合、正常にクライアントに信号を送ることができるようにすることを意味する場合は、はい。
+0

迅速な返信uriDiumありがとうございます。あなたの返信に基づいて、私は結論を下すことができます: 1.接続されたクライアントごとに追加のメモリ/リソースは作成されません。 2.私は、「そこからEndXXXメソッドへの呼び出しが例外をスローするか、ソケットから読み取られるゼロバイトを返すべきです」というような状況を処理するためのクリーンアップコードを持っていますが、Dispose/Closeを呼び出す必要はありません(サーバープログラムで)このエラーの原因となるクライアントで 私が間違っている場合は私を修正してください。 – Ytan

+0

1.スレッドを作成する必要はなく、OSによって処理されます。 2.おそらくcloseまたはdisposeを呼び出す必要はありません。そうした場合はおそらくObjectAlreadyDisposed例外が発生します。しかし、あなたはそうすることができ、100%確実にするためには、とにかくやることができます。この場合、ほとんどの場合、ObjectAlreadyDisposedExceptionがキャッチされます。 – uriDium

+0

私は、大丈夫です、ありがとうございます。 – Ytan

関連する問題