从NetworkStream读取前6个字节?

时间:2017-02-06 23:23:04

标签: c#

我通过tcpclient / networkstream发送图像(特别是屏幕截图)。要在接收端正确读取图像字节,我需要知道图像的长度。我打算做的是将缓冲区的前6个字节保存为图像大小(因为它似乎永远不会超过6个数字),然后从其上将剩余的缓冲区作为图像。我遇到的问题是我无法只读取前6个字节。

服务器代码

       int data = 0;

        byte[] readBuffer = new byte[getSelectedClient().ReceiveBufferSize];

        **data = stream.Read(readBuffer, 0, 5, readBuffer.Length);** <-- sort of thing im trying to do

        string pictureSize = Encoding.ASCII.GetString(readBuffer, 0, data);

        Console.WriteLine(pictureSize); //for debugging purposes

        string x = new Random().Next().ToString();

        FileStream f = new FileStream(x + ".bmp", FileMode.Create, FileAccess.Write);

        while (new FileInfo(x + ".bmp").Length != Convert.ToInt32(pictureSize))
        {
            **data = stream.Read(readBuffer, 6, readBuffer.Length);** <-- then it would read from the 6th byte, which would be the start of the image
            f.Write(readBuffer, 0, data);
        }

        f.Close();

        Process.Start(x + ".bmp");

        screenShotBTN.Enabled = true;

客户代码

MemoryStream ms = new MemoryStream();
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
               writeToStream(combineBytes(Encoding.ASCII.GetBytes(ms.Length.ToString()), ms.ToArray()));
ms.Close();


public static byte[] combineBytes(byte[] b1, byte[] b2)
    {
        byte[] b3 = new byte[b1.Length + b2.Length];
        Array.Copy(b1, 0, b3, 0, b1.Length);
        Array.Copy(b2, 0, b3, b1.Length, b2.Length);
        return b3;
    }

2 个答案:

答案 0 :(得分:1)

您正在实施的是长度前缀消息传递。

要记住的是,当您从网络流中读取时,您不一定会立即收到您正在寻找的所有字节(大多数情况下,当您在本地测试所有内容时,但您需要为此可能编程在最坏的情况下,你只会收到1个字节。

因此你应该进入一个州(awaitinglength,awaitingpayload)。 然后在等待长度时开始读取字节,然后在缓冲区中构建该数据。一旦你有了你的长度(在你的情况下为6个字节),那么你可以将状态切换到awaitingpayload,然后将其读入你的辅助缓冲区,直到你有完整的有效负载,然后你就可以了。

阅读Stephen Cleary关于消息框架的文章可能是值得的。通过阅读这些,我学到很多关于网络的知识。

http://blog.stephencleary.com/2009/04/sample-code-length-prefix-message.html

答案 1 :(得分:0)

我自己解决了这个问题。

服务器

int data = 0;

byte[] readBuffer = new byte[getSelectedClient().ReceiveBufferSize];

data = stream.Read(readBuffer, 0, 6); //only read first 6

string pictureSize = Encoding.ASCII.GetString(readBuffer, 0, data);

Console.WriteLine(pictureSize); //for debugging purposes

string x = new Random().Next().ToString();

FileStream f = new FileStream(x + ".bmp", FileMode.Create, FileAccess.Write);

while (new FileInfo(x + ".bmp").Length != Convert.ToInt32(pictureSize))
{
    data = stream.Read(readBuffer, 0, readBuffer.Length); 
    f.Write(readBuffer, 0, data);
}

f.Close();

Process.Start(x + ".bmp");

screenShotBTN.Enabled = true;

客户端代码

MemoryStream ms = new MemoryStream();
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Console.WriteLine(ms.Length.ToString());
writeToStream(combineBytes(Encoding.ASCII.GetBytes(ms.Length.ToString()), ms.ToArray()));
ms.Close();