TCP发送图像客户端和服务器
本文关键字:服务器 客户端 图像 TCP | 更新日期: 2023-09-27 18:09:49
我有一个客户机应用程序和一个服务器应用程序。客户端应用程序每40毫秒激活此函数:*注意nstream是一个NetworkStream实例。
private void SendScreen(NetworkStream nstream)
{
StreamWriter writer = new StreamWriter(nstream);
ScreenCapture sc = new ScreenCapture();
System.Drawing.Image img = sc.CaptureScreen();
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] buffer = new byte[ms.Length];
ms.Seek(0, SeekOrigin.Begin);
ms.Read(buffer, 0, buffer.Length);
Console.WriteLine(buffer.Length);
writer.WriteLine(buffer.Length);
writer.Flush();
nstream.Write(buffer, 0, buffer.Length);
}
这是接收图像的服务器应用程序代码:
private async void ShowImage()
{
while (true)
{
string num = await reader.ReadLineAsync();
Console.WriteLine(num);
int ctBytes = int.Parse(num);
byte[] buffer = new byte[ctBytes];
await stream.ReadAsync(buffer, 0, buffer.Length);
MemoryStream ms = new MemoryStream(buffer);
Image img = Image.FromStream(ms);
Bitmap bmp = new Bitmap(img);
this.Height = bmp.Height;
this.Width = bmp.Width;
this.BackgroundImage = bmp;
}
}
我想不出任何干扰这些动作的部分。在服务器应用程序的第一次迭代中,一切正常(尽管我看到的是黑屏而不是屏幕截图——但是发送和接收的字节数是匹配的)。在第二次迭代时,当我写入linenum时,它显示jibberish然后停止(因为它不能被解析为int)。
基本上我怀疑你有一个同步问题,当我试图重现你的问题(成功)。
通知即将到来的Bitmap
传输,无论是Header
还是单个Integer
。让不同步是非常容易的。
除非您想深入研究网络同步和流量控制,否则我建议在服务器和客户端之间的每个传输中使用单个TransmissionObject
(也许另一个反之亦然)
该对象具有潜力来存储必须传输的任何数据。(通过继承)
最后,当把对象放到网络流上时,你可以使用任何一致的 Serializer
Serializer
完成同步信息到需要的地方的所有工作(元信息,如长度和最后的内容)
在我的repro项目中,我想出了这个类来保存位图。
作为如何在服务器上使用它的示例:
public void Send(Bitmap bmp)
{
// prepare Bitmap
BitmapTransmission bt = new BitmapTransmission(bmp);
// try transmitting the object
try
{
// lock to exclude other Threads of using the stream
lock (m_objSendLock)
{
bt.Send(m_stream);
}
}
catch (BitmapTransmissionException ex)
{ // will catch any exception thrown in bt.Send(...)
Debug.Print("BitmapHeaderException: " + ex.Message);
///BitmapTransmissionException provides a Property `CloseConnection`
/// it will inform you whether the Exception is recoverable
}
}
其中m_objSendLock
是防止网络流并发访问的Object。m_stream
是连接到客户端的NetworkStream。Echo
是一个日志机制。
客户端可以通过
接收这些传输。 public void Receive() {
BitmapTransmission bt = bt.Receive(m_stream);
// check for exceptions maybe?
pictureBox1.Image = bt.Bitmap;
}
其中再次m_stream
,它的NetworkStream连接到服务器。
如果你想看一下(混乱但工作)的repro项目,请告诉我。