非同期サーバーのコードがあります。クライアントはヘッダーを送信します - データ ブロック + データ ブロックのサイズ。
サーバーは、最初にヘッダーを読み取り、次にデータ ブロックを非同期に読み取ります。
データブロックを読み取った後、スレッドを非同期にするために、ヘッダー読み取り部分の BeginRead を実行する必要があります。
問題:
私が DataCallBack を取得したとき、次のようになります。
int bytesRead = ns.EndRead(結果);
読み込むように要求したすべてのバッファを取得できません
mc.Client.GetStream().BeginRead(mc.DataBuffer, 0, size, new AsyncCallback(DataCallBack), mc);
クライアントが 1MB のデータを送信すると、異なる数の「bytesRead」を取得できます。
質問:
「BeginRead」に接続からすべてのデータを強制的に読み取る方法。ヘッダー - データの新しいループが発生するはずです。
MyClient - TcpClient の単なるラッパーです。
コード:
public void DoAcceptTcpClientCallback(IAsyncResult ar)
{
TcpListener listener = (TcpListener)ar.AsyncState;
TcpClient client = listener.EndAcceptTcpClient(ar);
client.NoDelay = false;
// client.ReceiveBufferSize = 1024*1024;
listener.BeginAcceptTcpClient(new AsyncCallback(DoAcceptTcpClientCallback), listener);
MyClient mc = new MyClient(client);
ContinueRead(0,mc);
}
public void ContinueRead(int size, MyClient mc)
{
if (size != 0)
{
mc.DataBuffer = new byte[size];
mc.Client.GetStream().BeginRead(mc.DataBuffer, 0, size, new AsyncCallback(DataCallBack), mc);
}
mc.Client.GetStream().BeginRead(mc.HeaderBuffer, 0, 4, new AsyncCallback(HeaderCallBack), mc);
}
private void HeaderCallBack(IAsyncResult result)
{
MyClient mc = (MyClient)result.AsyncState;
NetworkStream ns = mc.Stream;
int bytesRead = ns.EndRead(result);
if (bytesRead == 0)
throw new Exception();
mc.TotalLengs = BitConverter.ToInt32(mc.HeaderBuffer, 0);
ContinueRead(mc.TotalLengs, mc);
}
private void DataCallBack(IAsyncResult result)
{
MyClient mc = (MyClient)result.AsyncState;
NetworkStream ns = mc.Stream;
int bytesRead = ns.EndRead(result);
if (bytesRead == 0)
throw new Exception();
悪いコード - 読み取りが非同期になる - 同期
while (bytesRead < mc.TotalLengs)
{
bytesRead += ns.Read(mc.DataBuffer, bytesRead, mc.TotalLengs - bytesRead);
}
悪いコードを終わらせる
ContinueRead(0, mc);
ProcessPacket(mc.DataBuffer, mc.IP);
}