【问题标题】:Networkstream or Serializing sending images?网络流或序列化发送图像?
【发布时间】:2013-08-06 02:13:50
【问题描述】:

对此的新手,我一直在使用序列化来不断地发送图像数据。 这意味着我将图像保存在内存流中,并通过序列化发送。

但我不明白我应该使用序列化还是网络流。 我唯一要做的就是循环发送图像。

我一直试图让 Networkstream 工作,但它不符合我的要求,所以这是我的代码。由于某种原因,它只感知 1 张图像,当我使用序列化时,它会不断进行。

    private void Initialize()
    {
        NetSerializer.Serializer.Initialize(new Type[] { typeof(MemoryStream) });
        tcplisten = new System.Net.Sockets.TcpListener(IPAddress.Any, 1700);
        tcplisten.Start();

    }
    private void Listen()
    {
        try
        {
            using (TcpClient tt1 = tcplisten.AcceptTcpClient())
            {
                tt1.NoDelay = true;
                while (checkBox1.Checked)
                {
                    panel1.BackgroundImage = Image.FromStream(tt1.GetStream());
                }
            }
        }
        catch
        {
        }

    }

这里是发送:

    private void Send()
    {
        try
        {                
            string process = Proccessname.Text;               
            using (TcpClient tcp = new TcpClient())
            {

                tcp.NoDelay = true;
                while (capcon == true)
                {

                    if (tcp.Connected)
                    {
                        PrintWindow(process, tcp.GetStream());

                    }
                    else
                    {
                        tcp.Connect(adress);
                    }
                }
            }
        }
        catch
        {
        }  
    }

什么 PrintWindow(process, tcp.GetStream());做的很简单,截屏一个窗口(进程 = 进程的名称),然后将其保存在哪里(tcp.GetStream()),使其发送和流式传输(至少我认为是这样)。

它确实有点作用,如果我断开连接并连接等,它会发送图像,但我认为它非常随机,不知道为什么我必须这样做,我希望它继续发送,只要循环处于活动状态。

(这与序列化和 MemoryStream 完美配合(将位图保存在内存流中并在序列化中使用)。

所以这就像 2 个问题,取决于第一个问题的答案。

对于我的目的而言,(发送图像)、序列化或 NetworkStream 哪个更快? 如果 NetworkStream 更快,我怎样才能让它工作,我上面的代码有什么问题。

谢谢

          if (tcp.Connected)
                {
                    MemoryStream ms = new MemoryStream();

                    PrintWindow(process, ms);
                    panel1.BackgroundImage = Image.FromStream(ms);

                }

这行得通,因此它正在连接,并且数据正在保存(为此更改为 MemoryStream 而不是 NetworkStream)。

【问题讨论】:

  • 您的第二个 sn-p 代码实际上并没有显示 MemoryStream 是通过 NetworkStream 发送的,是吗?
  • 哦,看到了,ms = tcp.GetStream(),会解决这个问题的。
  • 示例代码的第二个 sn-p 仍然没有意义,因为您正在创建一个新的 TcpClient 并直接从中获取流,甚至没有连接到任何东西。
  • 将给出整个代码,因为我认为它没有任何意义。
  • 你确定这是你的全部代码吗?对我来说仍然没有多大意义。

标签: c# image performance stream


【解决方案1】:

您说断开连接时会获得图像。这是有道理的,因为您是直接从流中读取图像。由于流是NetworkStream,它不知道何时必须结束。

我的建议是在使用BinaryReader 接收/发送图像缓冲区时,在发送实际图像缓冲区之前添加图像缓冲区的大小,如下所示:

BinaryReader reader = new BinaryReader(netStream);
while (true) {
  // read how big the image buffer is
  int ctBytes = reader.ReadInt32();

  // read the image buffer into a MemoryStream
  MemoryStream ms = new MemoryStream(reader.ReadBytes(ctBytes));

  // get the image from the MemoryStream
  Image img = Image.FromStream(ms);

  // ...do something with img
}

发送时:

BinaryWriter writer = new BinaryWriter(netStream);
while (someCondition) {
  // get the image
  Image img = SomeImage();

  // save the image to a MemoryStream
  MemoryStream ms = new MemoryStream();
  img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);

  // get the image buffer
  byte[] buffer = new byte[ms.Length];
  ms.Seek(0, SeekOrigin.Begin);
  ms.Read(buffer, 0, buffer.Length);

  // write the size of the image buffer
  writer.Write(buffer.Length);

  // write the actual buffer
  writer.Write(buffer);
}

【讨论】:

  • 我不想使用 MemoryStream,直接保存到 NetworkStream 应该会更快。我正在尝试从序列化中加快速度。我必须使用字节数组的 MemoryStream。
  • 正如我的回答所说,你不能这样做,因为这样图像阅读器将无法知道流何时结束。
  • 嗯,很奇怪。或者不奇怪,这是有道理的。但问题是我对此提出了建议,写在 NetworkStream 中。但这与序列化有什么不同呢?
  • 不知道你在这里的序列化是什么意思,但这本质上是你自己的二进制序列化(我猜),通过发送缓冲区大小和图像缓冲区本身。
  • 我正在寻找发送图像的最快方式,但我缺乏知识会导致很多问题,这就是为什么我想看看 NetworkStream,与序列化相比。但遗憾的是,您的代码对我不起作用,不知道为什么。
【解决方案2】:

我稍微调整了代码,所以只是在这里写给其他人。 现在确定它是更好还是更糟。 这是发送部分,我跳过转换为 byte[] 并使用 MemoryStream。

                            using (MemoryStream ms = PrintWindow(process))
                        {
                            writer.Write(ms.Length);
                            writer.Write(ms.GetBuffer());
                        }

这里是接收部分:

panel1.BackgroundImage = Image.FromStream(new MemoryStream(reader.ReadBytes((Int32)reader.ReadInt64())));

将所有内容放在一个命令中。

当然有 BinaryWriter/Reader,但我没有把它们放在这里,因为我只是展示了我是如何更改代码的。

我在上面使用了 Angelo Geels 代码*

编辑:由于某种原因,它似乎只在 .bmp 中工作,不知道为什么,对我来说没有意义。

编辑 2:

这可以通过以下方式解决:

writer.Write(ms.GetBuffer(),0,(int)ms.Length);

想想就是这样。

【讨论】:

  • ms.GetBuffer() 并不总是返回与MemoryStream 本身长度相同的缓冲区,因此我将其读入代码中的缓冲区。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
相关资源
最近更新 更多