如何获取带有消息结尾字符的TCP消息中的所有数据?



我有一个TCP客户端/服务器应用程序,并且在本地计算机上运行良好。 但是,当我在另一台机器上使用客户端时,只传递了小消息(最多 20-30 字节(。 客户端需要读取较大数据的那一刻,如果会锁定。 我认为问题是客户端没有接收到一个 tcp 数据包中发送的所有数据。换句话说,我只调用了tcpClient.Client.Receive(tcpBuffer(,并假设tcpBuffer拥有它在本地机器上所做的所有数据。 现在,服务器发送的消息都以一个字节终止,该字节在消息 (0xFD( 中是唯一的。 我不知道如何处理这个问题。 所以一个问题是,NetworkStream.DataAvailable 是否为您提供了客户端或服务器上可用的数据? 我是否必须继续读取和循环,直到获得0xFD值? 如何有效地做到这一点? 所以基本上我想用下面这样的东西替换tcpClient.Client.Receive(tcpBuffer(:

private static byte[] GetTcpResponse()
{
int arrayLength = tcpClient.Client.Receive(tcpBuffer);
if (tcpBuffer[arrayLength - 1] == 0xFD)
{
return tcpBuffer;
}
else
{
//this is where I am hung up
}
}

因此,从上面可以看出我挂断的地方。我只是做另一个接收吗? 如果还没有数据怎么办? 谢谢,汤姆

TCP是基于流的协议,它不是基于数据报的协议。您不应依赖具有给定大小的接收数据报或您的数据位于任何给定的数据报边界上;您也不应期望在单个数据报(或任何给定数量的数据报(上接收所有数据。所以当你说:

我是否必须继续读取和循环,直到获得0xFD值?

是的,这就是重点;但是添加合理的超时和适当的异常检查,以便在连接失败并且永远不会获得该终止值时应用程序不会挂起。

然后,您的代码可以是这样的(除了超时、错误检查等(;我还没有测试过它,但它应该可以帮助你得到这个想法:

private static byte[] GetTcpResponse()
{
var data = new List<byte>();
var buffer = new byte[512]; //size can be different, just an example
var terminatorReceived = false;
while(!terminatorReceived)
{
var bytesReceived = tcpClient.Client.Receive(buffer);
if(bytesReceived > 0)
{
data.AddRange(buffer.Take(bytesReceived));
terminatorReceived = data.Contains(0xFD);
}
}
return data.ToArray();
}

最新更新