我在 C# 中有一個 TCP 請求回應模型,我正在與服務器通信。一旦服務器將資料寫入流,我正在讀取該資料。但stream.read讀取資料需要 2 秒。我需要在 2 秒內向服務器發送明確的確認,但由于讀取資料需要時間,我無法這樣做。下面是我讀取資料的代碼:
byte[] resp = new byte[100000];
var memoryStream = new MemoryStream();
int bytes;
String timeStamp = GetTimestamp(DateTime.Now);
Console.WriteLine("Before reading data: ");
Console.WriteLine(timeStamp);
do
{
bytes = stream.Read(resp, 0, resp.Length);
memoryStream.Write(resp, 0, bytes);
}
while (bytes > 0);
timeStamp = GetTimestamp(DateTime.Now);
Console.WriteLine("After reading data: ");
Console.WriteLine(timeStamp);
GenerateAcknowledgemnt(stream);
timeStamp = GetTimestamp(DateTime.Now);
Console.WriteLine("After sending ack: ");
Console.WriteLine(timeStamp);
以下是讀取的時間戳,格式為 yyyyMMddHHmmssff:
讀取資料前:202205061549 08 17
讀取資料后:202205061549 10 19
發送ack后:202205061549 10 20
我已經突出顯示了秒粗體。
如何減少stream.read閱讀時間?我也嘗試將網路流包裝在 BufferedStream 中,但沒有幫助。
uj5u.com熱心網友回復:
目前,您正在執行一個讀取回圈,該回圈一直持續到Read回傳一個非正數;在 TCP 中,這意味著您要等到另一端掛斷(或至少掛斷其出站套接字),直到您退出該回圈。我懷疑正在發生的事情是另一端放棄了你,關閉了他們的連接,然后你才能脫離回圈。
基本上:你不能那樣回圈;相反,您需要做的是仔細閱讀直到EOF ( ) 或直到您至少有一個完整的幀可以回應,在后一種情況下:回應then。這通常意味著回圈更像(偽代碼):bytes <= 0
while (TryReadSomeMoreData()) // performs a read into the buffer, positive result
{
// note: may have more than one frame per successful 'read'
while (TryParseOneFrame(out frame))
{
ProcessFrame(frame); // includes sending responses
// (and discard anything that you've now processed from the back-buffer)
}
}
(在這里決議幀意味著:遵循任何適用于從流中隔離單個訊息的規則 - 這可能意味著尋找諸如 CR/LF/NUL 之類的標記值,或者可能意味著檢查您是否有足夠的位元組來讀取標頭包括一個長度,然后檢查您是否有許多位元組,標頭指示為有效負載)
如果您用作積壓,這有點MemoryStream尷尬,因為丟棄步驟不方便;“管道” API 是專門為此設計的,但是:任何一種方式都可以作業。
其次:您可能更喜歡異步 IO,盡管同步 IO 可能適用于只有一個連接的簡單客戶端應用程式(但不適用于可能有很多連接的服務器)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/471931.html
上一篇:在群聊中發送以前的訊息
