我在写一个基本的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