我通过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;
}
答案 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();