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先生您的问题对我来说有点不清楚,请更新