【问题标题】:Using a NetworkStream to transfer a file使用 NetworkStream 传输文件
【发布时间】:2011-04-09 11:13:10
【问题描述】:

我在将文件从服务器程序传输到客户端时遇到问题。我想解决几个问题。首先是我将字节数组设置为 6000 字节大,并且始终保持该大小。有没有办法保持正确的文件大小?同样以现在的代码方式,程序挂起。当我将它从客户端的 while 循环中取出时,它就起作用了。救命!!

客户:

 private void button1_Click(object sender, EventArgs e)
    {   
        BinaryWriter binWriter; 
        int i = -1;
        Byte[] bytes = new Byte[6000];

        NetworkStream clientStream = connTemp.GetStream();
        byte[] outstream = Encoding.ASCII.GetBytes(txtMessage.Text);
        clientStream.Write(outstream, 0, outstream.Length);


        while (i != 0)
        {
            try
            {
                if (clientStream.CanRead)
                {
                    i = clientStream.Read(bytes, 0, bytes.Length);

                }
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                break;
            }
        }


        binWriter = new BinaryWriter(File.Open("C:\\SeanLaunch\\log.rxlog",FileMode.Create));
        binWriter.Write(bytes);
        binWriter.Close();

    }

}

服务器:

  Byte[] fileToSendAsByteArray = new Byte[6000];
  fileToSendAsByteArray = File.ReadAllBytes("C:\\Launch\\Test.rxlog");
  stream.Write(fileToSendAsByteArray, 0, fileToSendAsByteArray.Length);

编辑!!!:我修复了循环问题。

【问题讨论】:

    标签: c# .net .net-3.5 c#-3.0 networkstream


    【解决方案1】:

    一个问题是,即使您只从文件中读取一个字节,您也会将整个 6000 字节写入流中。

    使用FileStream 访问文件并将内容复制到 NetworkStream。 Framework 4.0 有一个很好的功能

    FileStream fs = new FileStream(...);
    fs.CopyTo(stream);
    

    您可以对客户端采取类似的方法,只是反过来,从 NetworkStream 复制到目标 Stream。

    在 Framework 4.0 之前,您可以实现自己的 CopyTo 功能。像这样的

    public static long CopyStream(Stream source, Stream target)
    {
      const int bufSize = 0x1000;
      byte[] buf = new byte[bufSize];
    
      long totalBytes = 0;
      int bytesRead = 0;
    
      while ((bytesRead = source.Read(buf, 0, bufSize)) > 0)
      {
        target.Write(buf, 0, bytesRead);
        totalBytes += bytesRead;
      }
      return totalBytes;
    }
    

    【讨论】:

    • 我需要这个来坚持 .Net 3.5
    • @Sean P,我为兼容 3.5 的 CopyStream 函数添加了示例实现。这些可以在互联网上找到,一角钱。
    • 我想你可能弄错了我的问题。我没有问题让文件通过。我的问题是该文件始终是 byte[] 的。有没有办法把它缩小到实际大小?我正在讨论首先传递文件大小,然后将 byte[] 初始化为正确的大小。
    • @Sean P,我认为这就是问题所在。这就是为什么我说“一个问题是您将整个 6000 字节写入流”。我提供 CopyTo/CopyStream 作为解决方案,因为它只会发送流的内容,所以在发送文件时它只会发送文件中的字节。这样您就无需通过网络发送文件大小。
    • 如果我这样做会怎样? byte[] fileToSendAsByteArray = new byte[File.ReadAllBytes("C:\\SeanLaunch\\Test.rxlog").Length];
    【解决方案2】:

    如果 CanRead 在 i 非零时保持为假,程序将永远循环。或者,它可能在 Read 调用中被阻止。

    调试您的接收端以了解发生了什么。它真的挂了,还是只是循环?

    添加代码以转储在每一端发送和接收的数据,以查看在问题出现之前您阅读的程度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-24
      • 2012-03-26
      • 2012-04-15
      • 1970-01-01
      • 2010-11-18
      • 2017-01-29
      相关资源
      最近更新 更多