繁体   English   中英

从NetworkStream读取前6个字节?

[英]Read First 6 Bytes From NetworkStream?

我正在通过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;
    }

您要实现的是“长度前缀”消息传递。

要记住的事情是,当您从网络流中读取数据时,不一定会立即收到要查找的所有字节(大多数情况下,在本地测试时,所有内容都可以,但是您需要进行编程以确保可能在最坏的情况下只能接收1个字节)。

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

阅读Stephen Cleary关于消息框架的文章可能是值得的。 通过阅读这些内容,我对网络的了解不多。

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

我自己解决了这个问题。

服务器

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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM