【问题标题】:File transfer succeeds only the first time, fails consuquently文件传输仅第一次成功,随后失败
【发布时间】:2012-01-28 01:02:52
【问题描述】:

  • 这是一个使用套接字 TCP 的文件传输发送/接收程序。此代码包含在客户端和服务器应用程序中,并且仅在第一次时才能正常工作。

  • 第二次,将接收的一方得到 0 并且传输完成。如何修复它以便可以多次使用?
    public static void sendFile(string filePath)
    {
        FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        string fileName = Path.GetFileName(filePath);
        byte[] fileData;
        try
        {
            //sending file name and file size to the server
            busy = true;
            fileSize = fs.Length;
            byte[] fileDetial = null;
            string detail =  fileName + "," + fileSize.ToString();
            fileDetial = Encoding.ASCII.GetBytes(detail);
            client.Send(fileDetial);
    
            //sending file data to the server
    
            fileData = new byte[packetSize];
            count = 0;
            sum = 0;
            Program.thFP.Start();                           // running transfer rate
            Program.fp.StatusLabel("Sending data...");
            transferRate.timeLeft();
    
            while (sum < fileSize)
            {
                fs.Seek(sum, SeekOrigin.Begin);
                fs.Read(fileData, 0, fileData.Length);
                count = client.Send(fileData, 0, fileData.Length, SocketFlags.None);
                sum += count;
                Program.fp.ProgressBarFileHandler(sum, fileSize);
            }
        }
        finally
        {
            busy = false;
            fs.Close();
            fileData = null;
            MessageBox.Show(string.Format("{0} sent successfully", fileName));
        }
    }
    

    我猜下面的代码完全没有问题..我认为问题出在 SENDFILE 方法中..但这里是 receiveFile 代码..它可能会有所帮助

    public static void ReceiveFile()
    {
    
        //receving file name and file size from server
        busy = true;
        byte[] commandData = new byte[1024];
        client.Receive(commandData);
        Console.WriteLine(Encoding.ASCII.GetString(commandData));
        string[] Command = Encoding.ASCII.GetString(commandData).Split(',');
        string fileName = Command[0];
        fileSize = Convert.ToInt64(Command[1]);
        Program.thFP.Start();                           // running transfer rate
        Program.fp.StatusLabel("Receiving data...");
        transferRate.timeLeft();
    
        // receiving the file data from server
        FileStream fs = new FileStream(@"D:\" + fileName, FileMode.Create, FileAccess.Write);
        byte[] fileData = new byte[packetSize];
        try
        {
            count = 0;
            sum = 0;
            while (sum < fileSize)
            {
                count = client.Receive(fileData,0,fileData.Length, SocketFlags.None);
                fs.Seek(sum, SeekOrigin.Begin);
                fs.Write(fileData, 0, fileData.Length);
                sum += count;
                Program.fp.ProgressBarFileHandler(sum,fileSize);
            }
        }
        finally
        {
            busy = false;
            fs.Close();
            fileData = null;
            MessageBox.Show(string.Format("{0} recevied successfully", fileName));
        }
    }
    
  • 【问题讨论】:

    • 如果您删除 try...finally 或至少添加一条 catch 语句以查看是否在某处抛出了异常,这可能会有所帮助。
    • 我删除了尝试,最后..应用程序没有停止或给我一个错误..我认为第一次传输后套接字出现问题:S
    • 您可以运行netstat 来查看端口处于什么状态。
    • 从命令提示符运行它:netstat /? 用于选项。
    • @ChrisO 服务器始终处于活动状态......并且工作正常......在我完全发送文件后......我可以关闭客户端并重新打开它并再次重新连接到服务器而无需重新启动服务器应用程序我可以用这种方式发送另一个文件..

    标签: c# .net sockets tcp file-transfer


    【解决方案1】:

    我已经修复了代码。问题出在SendFile 方法中,而正是在FileStream

    我应该丢弃它,这样我就可以用新路径再次初始化它

    finally
    {
        busy = false;
        fs.Dispose();   //here i fixed my mistake it was fs.Close()
        fileData = null;
        MessageBox.Show(string.Format("{0} sent successfully", fileName));
    }
    

    【讨论】:

      【解决方案2】:

      我建议您需要处理 FileStream。我建议将它包装在 using 块中,这样即使抛出异常,它也会始终被释放。

      // receiving the file data from server
      using (FileStream fs = new FileStream(@"D:\" + fileName, FileMode.Create, FileAccess.Write))
      {
          byte[] fileData = new byte[packetSize];
          try
          {
              ...same code as before here...
          }
          finally
          {
               ...same code as before here...
          }
      }
      

      我总是建议将流包装在 using 块中。这意味着,如果您稍后返回并编辑代码,您引入一个在完成后不会处理流的代码路径的危险会更小。

      我还将重组代码,使您的“成功”消息不在 finally 块中 - 它可能应该在 try 块的末尾。您当前的实现将在抛出异常时显示成功消息 - 因此文件可能会成功。

      【讨论】:

      • 确实..你是绝对正确的..它应该按照你说的方式编辑和更新..但是代码是关于一个问题并且它已经修复了:)无论如何
      猜你喜欢
      • 1970-01-01
      • 2013-01-07
      • 1970-01-01
      • 2020-03-28
      • 2020-09-13
      • 2012-07-31
      • 2020-10-15
      • 1970-01-01
      • 2012-02-09
      相关资源
      最近更新 更多