C# 使用NetworkStream的图像流的信号结束
我有一个客户机-服务器场景,客户机每秒向服务器发送图像。我不想每次发送图像以表示流结束时都关闭连接。我希望保持网络流开放,以减少重新建立连接的开销。如何发出图像流结束的信号 在发送图像字节后,我尝试使用C# 使用NetworkStream的图像流的信号结束,c#,C#,我有一个客户机-服务器场景,客户机每秒向服务器发送图像。我不想每次发送图像以表示流结束时都关闭连接。我希望保持网络流开放,以减少重新建立连接的开销。如何发出图像流结束的信号 在发送图像字节后,我尝试使用NetworkStream.Flush(),然后发送一个ASCII编码的字符串来表示图像结束,但是,根据Microsoft的文档,NetworkStream.Flush()方法没有效果,“因为NetworkStream没有缓冲,所以它对网络流没有影响” 我怎样才能解决这个问题 客户: client
NetworkStream.Flush()
,然后发送一个ASCII编码的字符串来表示图像结束,但是,根据Microsoft的文档,NetworkStream.Flush()
方法没有效果,“因为NetworkStream没有缓冲,所以它对网络流没有影响”
我怎样才能解决这个问题
客户:
client.Connect(_host, _port);
Console.WriteLine("Connected");
using (NetworkStream stream = client.GetStream())
{
while (_isRunning && client.Connected)
{
byte[] buffer = CaptureScreen();
Console.WriteLine("Sending {0} bytes", buffer.Length);
stream.Write(buffer, 0, buffer.Length);
Thread.Sleep(1000);
}
}
服务器:
using (NetworkStream stream = client.GetStream())
{
while (_isRunning && client.Connected)
{
byte[] buffer = new byte[16384];
using (MemoryStream memoryStream = new MemoryStream())
{
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
{
_form.ConsoleWriteLine($"Received {bytesRead} bytes");
// TODO: If end of image stream break from read loop
memoryStream.Write(buffer, 0, bytesRead);
}
Image image = Image.FromStream(memoryStream);
_form.UpdateImage(image);
}
}
}
更新 首先,你需要弄清楚打开和关闭连接的开销是否真的那么糟糕,我的直觉是这将是最小的。。。如果你完全不能接受,那么你真的只有两个可靠的选择。发送某种表示结束的字节组合。或者在每个图像之前发送一个大小,以便您知道大小和结束 原创 备注此方法将数据读入缓冲区参数并返回 成功读取的字节数如果插座已关闭,则 Read方法返回0。读取操作读取尽可能多的数据 可用,最多为size参数指定的字节数。 如果远程主机关闭连接以及所有可用数据 已收到,则Read方法立即完成并返回 零字节 你所需要做的就是关闭客户端
...
if(SomeCondition)
break;
尽管您可能还希望捕获服务器上的适当异常,但它们可以并且将会发生更新 首先,你需要弄清楚打开和关闭连接的开销是否真的那么糟糕,我的直觉是这将是最小的。。。如果你完全不能接受,那么你真的只有两个可靠的选择。发送某种表示结束的字节组合。或者在每个图像之前发送一个大小,以便您知道大小和结束 原创 备注此方法将数据读入缓冲区参数并返回 成功读取的字节数如果插座已关闭,则 Read方法返回0。读取操作读取尽可能多的数据 可用,最多为size参数指定的字节数。 如果远程主机关闭连接以及所有可用数据 已收到,则Read方法立即完成并返回 零字节 你所需要做的就是关闭客户端
...
if(SomeCondition)
break;
尽管您可能还希望在服务器上捕获适当的异常,但它们可以并且将发生您可以在发送图像内容之前发送图像大小
stream.Write(BitConverter.GetBytes(buffer.Length), 0, 4);
stream.Write(buffer, 0, buffer.Length);
在服务器端,收到确认字节后立即停止
int read = stream.Read(buffer, 0, 4);
int imageSize = BitConverter.ToInt32(buffer, 0);
int bytesRead, totalBytesRead = 0;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
{
totalBytesRead += bytesRead;
if(totalBytesRead == imageSize)
{
//Save image
}
else if(totalBytesRead > imageSize)
{
//May happens, split the buffer.
}
}
您可以在发送图像内容之前发送图像大小
stream.Write(BitConverter.GetBytes(buffer.Length), 0, 4);
stream.Write(buffer, 0, buffer.Length);
在服务器端,收到确认字节后立即停止
int read = stream.Read(buffer, 0, 4);
int imageSize = BitConverter.ToInt32(buffer, 0);
int bytesRead, totalBytesRead = 0;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
{
totalBytesRead += bytesRead;
if(totalBytesRead == imageSize)
{
//Save image
}
else if(totalBytesRead > imageSize)
{
//May happens, split the buffer.
}
}
关闭连接是我试图避免的。我不想每秒重新建立连接的开销。@coffee先生您的问题对我来说有点不清楚,更新关闭连接是我试图避免的。我不想每秒重新建立连接的开销。@coffee先生您的问题对我来说有点不清楚,请更新