[英]TCP sending images client and server
我有一个客户端应用程序和一个服务器应用程序。 客户端应用程序每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;
}
}
我想不出任何会干扰这些动作的部分。 在服务器应用程序的第一个迭代中,一切正常(尽管我看到黑屏而不是屏幕截图-但发送和接收的字节数匹配。)在第二个迭代中,当我写行num时,它显示为乱码,然后停止(因为无法将其解析为int)。
从本质上讲,当我尝试(成功)重现您的问题时,我怀疑您有同步问题。
宣布即将进行的Bitmap
传输的是Header
还是单个Integer
。 完全不同步非常容易。
除非您想深入研究网络同步和流量控制,否则我建议对服务器和客户端之间的每次传输都使用一个TransmissionObject
(反之亦然)
该对象有可能存储必须传输的任何数据 。 (通过继承)
最后,将对象放在网络流上时,可以使用任何一致的 Serializer
Serializer
完成将信息同步到所需位置的所有工作(元信息,例如长度,最后还有内容)
那么在我的摄制项目,我想出了这个类来保存位图。
作为如何在服务器上使用它的示例:
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
是防止在网络流上进行并发访问的对象。 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项目,请告诉我们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.