2011-02-06 22 views
1

私は自分のアプリケーションでマスター/スレーブアーキテクチャを実装しています。.Netソケットクライアントデータ受信の問題

マスターはデータベースからジョブをポーリングして、スレーブ間でジョブを配布します。私はソケット接続を使用して、マスタとスレーブ間の接続を維持し、ジョブをクライアントに送信しています。

マスタがプロセスを開始すると、あるスレッドがジョブキューの作成を開始し、別のスレッドがジョブをキューから取得して、接続されているすべてのスレーブに1つずつ送ります。スレーブがジョブを終了すると、マスターに確認応答を送信します。マスターは、フリーであり、マスターはそのクライアントにジョブを再度送ります。キューが空の場合、マスターはただちにクライアントに確認応答を送信します。その後、クライアントは再び確認応答をマスターに送信し、マスターは再びキューをチェックし、利用可能であればジョブを送信します。このプロセスは、マスターがすべてのジョブが完了したと判断するまで続行します。

肯定応答は何らかの定数値に過ぎません。クライアントがこの定数値を受け取るたびに、クライアントは同じ値をマスターに送り返し、マスターがこの定数値を受け取ると、キュー内で使用可能な場合はジョブを送信し、そうでない場合は同じ値をクライアントに返します。このようにして、マスタとスレーブは、ジョブがすべて完了するまで通信を続けます。

私は、非同期ソケットを使用しているc#windows serverで作業しています。

私の問題は、クライアント側で受信されているデータを処理する際に、クライアントが重複して値を取得してしまうことです。これは、クライアントソケットの次のイベントで起こっている:このイベントに

public void OnDataReceived(IAsyncResult asyn) 

    { 

     SocketPacket theSockId = null; 

     try 

     { 

      theSockId = (SocketPacket)asyn.AsyncState; 

      int iRx = theSockId.currentSocket.EndReceive(asyn); 

      char[] chars = new char[iRx + 1]; 

      System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder(); 

      int charLen = d.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0); 

      System.String szData = new System.String(chars); 

      if (OnDataRecievedFromMaster != null) 

      { 

       OnDataRecievedFromMaster(Convert.ToInt32(szData), theSockId.hostName); 

      } 

      //richTextRxMessage.Text = richTextRxMessage.Text + szData; 

      WaitForData(theSockId.hostName); 

     } 

     catch (ObjectDisposedException) 

     { 

      System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n"); 

     } 

     catch (SocketException se) 

     { 

      if (se.ErrorCode == 10054) // Error code for Connection reset by peer 

      { 

       //string msg = "Client " + socketData.hostName + " Disconnected" + "\n"; 

       //AppendToRichEditControl(msg); 

       // Remove the reference to the worker socket of the closed client 

       // so that this object will get garbage collected 

      } 

     } 

     finally 

     { 





     } 

    } 

、szdataの値は、実際に送られたものをマスター元の値ではありません。ほとんどの場合、値が繰り返されます。私は整数値をクライアントまたはサーバに送ります。文字列はありません。

私がこれを得ている理由の入力は、本当に感謝します。

+0

あなたの文字列の扱いはむしろ奇妙です(バグ:バッファが小さすぎます。Encoding.GetStringだけ使用できませんか?)。また、読んでも「メッセージ」全体が返ってくると思われるようです。 TCPにはメッセージがありません。読み取りは、送信されたバイト数より少ないバイト数を返すことができます。また、なぜ文字列として整数を送信していますか?固定長の4バイトメッセージとして送信してください。 – usr

答えて

0

2つのスレッド(マスターとスレーブの両方を同期せずに実行させる場合は、問題が発生する可能性があります)をどのようにスケジューリングしますか。スレーブがマスタのデータなしでデータのチェックを続けているとします。その場合、クライアント側で複数の値が繰り返される可能性があります。このエラーが時々だけ発生していて、常に並行性のバグを指しているとは限りません。

+2

マスタは、スレーブからジョブを処理することが自由であることを確認しない限り、同じスレーブにジョブを供給しません。私はこの方法でマスターと奴隷を同期させていると思います。もし私が何かを欠けているなら、私のコードを再チェックすることができます。あなたのご意見ありがとう、本当に感謝します。 – Bikswan

関連する問題