複数のクライアントを受け入れる TCP ソケット サーバーを作成しようとしています。しかし、ここ数日、特定の障害を克服できていません。問題を TcpClient.BeginRead( callbackMethod ) メソッドにあると切り分けたと思います。
基本的に、個別のクライアントがこのメソッドをアクティブにしますが、コールバックは実際に送信ストリームにデータを送信するまで呼び出されたりトリガーされたりしません。ただし、ストリーム経由で入ってくるバイトに対して実行する encoding.ASCII.Getstring() メソッドは、beginread メソッドが開始された順序に応じて、不要な「0/0/0/」を出力します。なぜこうなった?なんで?助けてください。
順番に状況/シナリオ
イベント 1.) ClientOne Connects は、非同期コールバックで BeginRead をトリガーします (現在、コールバックはデータを待機しています)。
イベント 2.) ClientTwo Connects は、非同期コールバックで BeginRead をトリガーします。(現在、コールバックはデータを待っています)
イベント 3.) ClientOne が最初にメッセージを送信した場合、データは確実に処理されますが、Encoding.ASCII.GetString(3 つの引数) はすべてのバイトに対して「0/」を出力します。ClientTwo の BeginRead が ClientOne の BeginRead に干渉していると思います。
イベント 3. (4 ではない)) ClientTwo が最初にメッセージを送信した場合、データは処理され、Encoding.ASCII.GetString(3 つの引数) を使用して正しくデコード/文字列化されます。
ソースコード
void onCompleteAcceptTcpClient(IAsyncResult iar){TcpListener tcpl = (TcpListener)iar.AsyncState;
try
{
mTCPClient = tcpl.EndAcceptTcpClient(iar);
var ClientEndPoint = mTCPClient.Client.RemoteEndPoint;
Console.log(ClientEndPoint.ToString());
Console.log("Client Connected...");
_sockets.Add(mTCPClient);
tcpl.BeginAcceptTcpClient(onCompleteAcceptTcpClient, tcpl);
mRx = new byte[512];
_sockets.Last().GetStream().BeginRead(mRx, 0, mRx.Length, onCompleteReadFromTCPClientStream, mTCPClient);
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
void **onCompleteReadFromTCPClientStream**(IAsyncResult iar)
{
foreach (string message in messages)//For Testing previous saved messages
{
printLine("Checking previous saved messages: " + message);
}
TcpClient tcpc = new TcpClient();
int nCountReadBytes = 0;
try
{
tcpc = (TcpClient)iar.AsyncState;
nCountReadBytes = tcpc.GetStream().EndRead(iar);
printLine(nCountReadBytes.GetType().ToString());
if (nCountReadBytes == 0)
{
MessageBox.Show("Client disconnected.");
return;
}
string foo;
/*THE ENCODING OUTPUTS "0/" FOR EVERY BYTE WHEN AN OLDER CALLBACK'S DATA IS DECODED*/
foo = Encoding.ASCII.GetString(mRx, 0, nCountReadBytes);
messages.Add(foo);
foreach (string message in messages)
{
console.log(message);
}
mRx = new byte[512];
//(reopens the callback)
tcpc.GetStream().BeginRead(mRx, 0, mRx.Length, onCompleteReadFromTCPClientStream, tcpc);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}