我试图通过网络流发送一个对象(在我的情况下是一个图像)。然而,我没有得到完整的图像…
这是客户端代码:
private void Form1_Load(object sender, EventArgs e)
{
TcpClient c = new TcpClient();
c.Connect("10.0.0.4", 10);
NetworkStream ns = c.GetStream();
Bitmap f = GetDesktopImage();
byte[] buffer = imageToByteArray(f);
byte[] len = BitConverter.GetBytes(buffer.Length);
MemoryStream stream = new MemoryStream();
stream.Write(len, 0, len.Length);
stream.Write(buffer, 0, buffer.Length);
stream.Position = 0;
stream.CopyTo(ns);
}
正如你所看到的,我首先将整个内容写入常规MemoryStream(因为我不想使用两次NetworkStream
-只有这样,我才将MemoryStream
的内容复制到NetworkStream
中。
服务器代码:
private void Form1_Load(object sender, EventArgs e)
{
TcpListener tl = new TcpListener(IPAddress.Any, 10);
tl.Start();
TcpClient c = tl.AcceptTcpClient();
network = new NetworkStream(c.Client);
byte[] buff = new byte[4];
network.Read(buff, 0, 4);
int len = BitConverter.ToInt32(buff, 0);
buff = new byte[len];
network.Read(buff, 0, buff.Length);
pictureBox1.Image = byteArrayToImage(buff);
Thread th = new Thread(method);
}
现在当我运行两个应用程序时,我只获得捕获图像的顶部部分…更奇怪的是,直接写入网络流是完美的……例如:
ns.Write(len, 0, len.Length);
ns.Write(buffer, 0, buffer.Length);
这将工作得很好,我会得到完整的图像在另一边。但我不想使用它两次(这只是一个例子,在我的实际项目中,我将不得不使用它很多,所以我想尽可能减少网络使用,而不是为每一个数据触发它)。
为什么使用简单的CopyTo
方法不起作用?
我将感激任何帮助!
谢谢
在您的服务器代码中,您忽略了NetworkStream的结果。读取的实际字节数。这个可以小于实际请求的字节数。你需要一直调用Read,直到你收到你需要的所有字节。
您看到的1次或多次写入之间的差异与网络堆栈中的缓冲/定时有关。我怀疑你只是在做一次写的时候幸运地收到了图像——这并不总是如此!如前所述,需要处理Read的结果。
代码示例:
void ReadBuffer(byte[] buffer, int offset, int count)
{
int num;
int num2 = 0;
do
{
num2 += num = _stream.Read(buffer, offset + num2, count - num2);
}
while ((num > 0) && (num2 < count));
if (num2 != count)
throw new EndOfStreamException
(String.Format("End of stream reached with {0} bytes left to read", count - num2));
}