我在寫一個基本的TCP/IP服務器來接收來自現有客戶端的消息。目前,我能夠接收單緩衝和多緩衝消息。客戶端發送一組多條消息時會出現問題。與其將每個消息作爲單個通信發送,它希望打開流,並且在流再次關閉之前,將集合中的所有消息一個接一個地發送。我在下面的編輯片段編碼此:NetworkStream.DataAvailable更新緩慢
private void AcceptMessage(IAsyncResult ar)
{
String receivedMessage = "";
// Only run if the server is listening. Otherwise, an exception will be thrown.
if (isListening)
{
ASCIIEncoding encoder = new ASCIIEncoding();
try
{
TcpListener listener = (TcpListener)ar.AsyncState;
using (TcpClient client = listener.EndAcceptTcpClient(ar))
using (NetworkStream stream = client.GetStream())
{
int bytesRead;
int totalBytes = 0;
stream.ReadTimeout = ReadTimeout;
do
{
byte[] receivedBytes = new byte[BufferSize];
StringBuilder message = new StringBuilder();
bytesRead = 0;
do
{
try
{
if (stream.CanRead)
bytesRead = stream.Read(receivedBytes, 0, BufferSize);
}
catch (...Exception Handling...)
if (bytesRead == 0)
break;
message.Append(encoder.GetString(receivedBytes, 0, bytesRead));
totalBytes += bytesRead;
} while (bytesRead == BufferSize); // Allow for multiple buffers in a single message
byte[] ack = encoder.GetBytes(GetAck(message.ToString(), ackNak, status, statusMessage));
stream.Write(ack, 0, ack.Length);
...Message Processing...
} while (stream.DataAvailable); // Allow for multiple messages
}
}
catch (...Error Handling...)
finally { ...Cleanup...}
}
}
這個問題是在第二while (stream.DataAvailable);
當檢查時,DataAvailable發送一組消息的時候顯示的是假的,但如果我把一個破下一行它會表現真實。換句話說,在數據可用之前它正在檢查數據是否可用。我可以通過在檢查是否有更多消息之前增加一秒延遲來解決此問題,但在100個案例中有99個,這將是不必要的延遲。由於客戶端一次只能發送一條消息(或一組消息),因此在繁忙時間內可能會增加大量時間來接收消息。
有沒有更好的方法來確定是否有更多的消息掛起(沒有客戶端修改)?謝謝!
編輯
我更改了代碼以包含建議。我添加了暫停,並將第一張支票從stream.DataAvailable
更改爲bytesRead == BufferSize
。我無法訪問客戶端軟件,因此我無法添加EOM傳輸。我也無法保證多個消息是以單個流還是多個單獨的流發送。我還沒有想出如何判斷是否有更多的消息未決。我不能讓流打開,因爲這阻止了下一次傳輸。
我標記爲Elgonzo作爲答案,因爲他幫助我的問題的大部分方面。它仍然沒有回答如何判斷是否有消息掛起,這可能是不可能的,但我的經理認爲,一旦連接打開,我們應該將其作爲專用連接打開。這是有效的,因爲我們的聽衆只能通過具有一致流量的內部安全網絡與單個設備進行通信。如果在一段時間內沒有活動,我們將增加暫停時間。
有幾個,如果任何正確的使用可用,這不是其中之一。您應該阻止並閱讀,直到您有所需,或使用異步或非阻塞I/O同上。 – EJP