目前正在编写一些TCP套接字代码并遇到一个小问题。
基本上我感到困惑的是以下几行代码。
NetworkStream clientStream = tcpClient.GetStream();
List<Byte> fullMessage = new List<Byte>();
Byte[] message = new Byte[4096];
Byte[] currentMessage = new Byte[4096];
Int32 bytesRead = 0;
if (clientStream.CanRead)
{
do
{
bytesRead = clientStream.Read(message, 0, 4096);
Array.Resize<Byte>(ref currentMessage, bytesRead);
Array.Copy(message, currentMessage, bytesRead);
fullMessage.AddRange(currentMessage);
} while (clientStream.DataAvailable);
}
特别是关于处理事实的最佳方法,即使消息字节数组声明为4096字节,检索的数据量是任意的,无法计算。
我处理响应的方式是合理的解决方案还是有更好的方法? (IE:基于bytesRead值创建一个新的大小的数组)
答案 0 :(得分:1)
如果您知道该消息不会超过4096字节,那么您可以编写如下内容:
int totalBytesRead = 0;
int bytesRead;
while ((bytesRead = clientStream.Read(message, totalBytesRead, message.Length - totalBytesRead)) !=0)
{
totalBytesRead += bytesRead;
}
totalBytesRead
用于告知clientStream.Read
将其复制的数据放在何处。
clientStream.Read
将返回0。
请注意,使用此设置,您不能读取超过message.Length
个字节的内容。如果你的数据包可能更大,那么我建议你的缓冲区更大。我不建议不断调整数组大小,因为这最终会破坏大对象堆(如果消息大于80 KB),并且在某些时候你必须设置一个消息大小的最大值 - 即使你处理“任意大”的消息。
答案 1 :(得分:1)
使用内存流:
NetworkStream clientStream = tcpClient.GetStream();
MemoryStream messageStream = new MemoryStream();
byte[] inbuffer = new byte[65535];
if (clientStream.CanRead)
{
do
{
var bytesRead = clientStream.Read(inbuffer, 0, buffer.Length);
messageStream.Write(inbuffer, 0, bytesRead);
} while (clientStream.DataAvailable);
}
messageStream.Position = 0;
var completeMessage = new byte[messageStream.Length];
messageStream.Write(completeMessage, 0, messageStream.Length);