TCPClient.Read读取低至4个字节的块

时间:2015-01-27 16:59:21

标签: c# sockets tcpclient

我完全理解如果数据尚未到达,我无法读取分配的最大值。但以4字节的速度读取是否合理?我的意思是,如果我收到一个100000字节的图像,这将花费太长时间。

我收到或发送图片时是否存在明显问题?

****澄清:下面的rLength每次都会改变,有时我只会收到4个字节,而在此循环中只有4个字节,而其他时间我得到3000并且循环中只有3000个。我很确定有更多的数据,但它似乎只是在每次循环读取x量****

这是服务器端的接收代码

int totalBuffer, totalRecieved = 0;
byte[] totalBufferByte = new byte[4];
byte[] buffer = new byte[0];
byte[] tbuffer;
int rLength, prevLength;
stream.Read(totalBufferByte, 0, totalBufferByte.Length);
totalBuffer = BitConverter.ToInt32(totalBufferByte, 0);
byte[] buf = new byte[8192];
while (totalBuffer > totalRecieved)
{

    rLength = stream.Read(buf, 0, buf.Length);
    totalRecieved = rLength + totalRecieved;
    Console.WriteLine("totalRecieved len: " + totalRecieved + " " + totalBuffer + " " + rLength + " " + buf.Length);
    if (rLength < buf.Length)
    {
        byte[] temp = new byte[rLength];
        Array.Copy(buf, temp, rLength);
        buf = temp;
    }
    prevLength = buffer.Length;
    tbuffer = buffer;
    buffer = new byte[buffer.Length + rLength];
    Array.Copy(tbuffer, buffer, tbuffer.Length);
    buf.CopyTo(buffer, prevLength);
}

这是发送代码

public void SendResponse(int command, Object[] args)
{
    if (ClientSocket == null)
    {
        Console.WriteLine("Command: ClientSocket");
        return;
    }
    var serverStream = this.ClientSocket.GetStream();
    if (!serverStream.CanRead || !serverStream.CanWrite)
    {
        Console.WriteLine("Command: serverStream Error");
        return;
    }
    byte[] toSend = null;
    switch (command)
    {
        // 0 - genneral, 1 - handshake response
        case 0:
            toSend = Encoding.ASCII.GetBytes(args[0].ToString());
            break;
        case 1:
            Rectangle bounds = Screen.GetBounds(Point.Empty);
            using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb555))
            {
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
                }
                toSend = ImageToByte(bitmap);
            }
            break;
    }

    try
    {
        byte[] bufferedToSend = new byte[toSend.Length + 4];
        byte[] lengthOfSend = BitConverter.GetBytes(toSend.Length);
        Array.Copy(lengthOfSend, bufferedToSend, 4);
        toSend.CopyTo(bufferedToSend, 4);
        serverStream.Write(bufferedToSend, 0, bufferedToSend.Length);
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

1 个答案:

答案 0 :(得分:1)

这至少是问题的一部分:

rLength = stream.Read(buf, 0, buf.Length);
...
if (rLength < buf.Length)
{
    byte[] temp = new byte[rLength];
    Array.Copy(buf, temp, rLength);
    buf = temp;
}

基本上,您将下一次阅读限制在最多之前读取的大小。

目前尚不清楚你真正想要做什么,但听起来你应该有类似的东西:

byte[] lengthBuffer = new byte[4];
int lengthRead = stream.Read(lengthBuffer, 0, lengthBuffer.Length);
// TODO: Throw or loop if you haven't read 4 bytes...
int length = BitConverter.ToInt32(totalBufferByte, 0);
byte[] buffer = new byte[length];
int lengthRead = 0;
while (lengthRead < length)
{
    int chunkRead = stream.Read(buffer, lengthRead,
                                length - lengthRead);
    if (chunkRead == 0)
    {
        throw new IOException(
            "Stream ended after reading {0} out of {1} bytes",
            lengthRead, length);
    }
    lengthRead += chunkRead;
}

换句话说,你应该总是要求阅读“不管剩下多少数据” - 而不必将数据复制到新的单独字节数组中。