TcpClient读取数据和填充数组

时间:2011-04-18 03:17:24

标签: c# sockets stream bytearray

目前正在编写一些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值创建一个新的大小的数组)

2 个答案:

答案 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);