私は自分のアプリケーションでマスター/スレーブアーキテクチャを実装しています。.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の値は、実際に送られたものをマスター元の値ではありません。ほとんどの場合、値が繰り返されます。私は整数値をクライアントまたはサーバに送ります。文字列はありません。
私がこれを得ている理由の入力は、本当に感謝します。
あなたの文字列の扱いはむしろ奇妙です(バグ:バッファが小さすぎます。Encoding.GetStringだけ使用できませんか?)。また、読んでも「メッセージ」全体が返ってくると思われるようです。 TCPにはメッセージがありません。読み取りは、送信されたバイト数より少ないバイト数を返すことができます。また、なぜ文字列として整数を送信していますか?固定長の4バイトメッセージとして送信してください。 – usr