sslストリーム(Webサイトから)からのデータを画面に表示しようとしています。データがいつ到着するかわからないので、バイトが読み取られるまでストリームから読み取りを続ける別のスレッドを使用しました。これは完全に機能しますが、CPU使用率は25%に跳ね上がり、そこにとどまります(これは、最大使用量で1スレッド、私のPCには4スレッドです)。スレッドがwhileループでスタックしているため、これは少し意味がありますが、ThreadクラスのインスタンスがCPUのスレッド全体を消費することは期待していませんでした(単純なClient/を使用している場合はこれが発生していないことを誓うことができます。サーバーアプリケーション)。
接続が初期化されるとすぐにスレッドの実行が開始され、ユーザーはいつでもWebサイトにデータを送信でき、アプリケーションは応答を出力することになっています。これに対する代替ソリューションは何でしょうか?SslStreamを削除して、他のものを使い始める必要がありますか?
この別のスレッドで実行されるコードは次のとおりです。
void ReadDataAsync(Object obj) {
byte[] buffer = new byte[65536]; //65536, make sure all bytes can be
//from a single packet
int bytesRead = -1;
while (true) {
//It makes sense for sslStream.Read to block until bytes have been
//read, but it doesn't. Which is why I'm checking if bytesRead!=0
bytesRead = sslStream.Read(buffer, 0, 65536);
if (bytesRead != 0) {
Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, bytesRead));
buffer = new byte[65536];
}
}
}
みなさん、ありがとうございました。
編集:
「gt」が示唆するように、代わりにBeginReadとEndReadを使用してみました。このために、ユーザーからリクエストが送信されるたびにBeginReadを使用しています。すべてのデータを受信したら、画面に印刷します。これはうまくいくようですが、将来問題が発生するかどうか心配です。パケットがめちゃくちゃになる可能性はありますか?たとえば、EndReadが最初のパケットの最後に0を返さず、2番目のパケットを読み取り続ける可能性はありますか?それが可能であれば、どうすればこれを解決できますか?受信したデータはhttp層の本体にすぎないため、パケットの長さを知るために事前にIP層にアクセスすることはできません。
public void SendData(byte[] message) {
sslStream.Write(message);
sslStream.Flush();
//Start reading for response (if not already reading)
if (sslStream.CanRead) {
sslStream.BeginRead(buffer, 0, BufferSize, ReadData, null);
}
}
void ReadData(IAsyncResult ar) {
int bytesRead = sslStream.EndRead(ar);
if (bytesRead > 0) {
//data may be on their way so start reading again
message.Append(Encoding.UTF8.GetString(buffer, 0, bytesRead));
sslStream.BeginRead(buffer, 0, BufferSize, ReadData, null);
Console.WriteLine("Data received but more may be on their way...");
} else {
//All data arrived (Checking if length is more than 0 since all the
//data may had already arrived in the previous check (above)
if (message.ToString().Length > 0) {
Console.WriteLine(message.ToString());
//Clear StringBuilder and reset buffer.
message.Clear();
buffer = new byte[BufferSize];
}
}
}
再度、感謝します