用TIdTcpServer、TIdTcpClient写的文件传输程序,为什么服务器端在传完以后会出错?在线等...

                            
程序是根据别人的示例自已修改完成的,运行他的文件传输程序没出错,但自已写的这个在传完文件以后,服务器端会出现“线程超时”、作些修改会出现关闭窗口时出现“无效窗口句柄”之类的错误,我对这方面完成是菜鸟,整了很久就是找不到原因,望高手们指点指点。。。   
  以下是部分主要代码:  
   
   
  //   S_P2P   为TIdTcpServer,C_P2P为TIdTcpClient,它们放在同一程序中  
  //   文件流在双方同意传输后建立  
   
  procedure   TfrmNowChat.S_P2PExecute(AThread:   TIdPeerThread);  
  var  
      cmd:   string;   //接收到客户端的字符串信息  
      ASize:   Integer;   //需要传输的流大小  
  begin  
      with   AThread.Connection   do   //已经连街上的一个进程  
      begin  
          cmd   :=   UpperCase(ReadLn);   //客户端发送的命令字符串  
          if   cmd   =   'BEGIN'   then   //开始传输  
          begin  
              //告诉远程传输文件的大小和文件名  
              WriteLn(Format('%d|%s',   [F_AFileStream.Size,   ExtractFileName(FTranFile.FileName)]));  
              labProsStat.Caption   :=   '准备传输...';  
              labDoingStat.Visible   :=   true   ;  
              bsSkinGauge1.Visible   :=   true   ;  
              Exit;  
          end;  
          if   cmd   =   'END'   then             //传输完成  
          begin  
              labProsStat.Caption   :=   '已完成';  
              TsCancle   ;       //   重置相关变量  
              Exit;  
          end;  
          if   cmd   =   'CANCEL'   then     //传输取消  
          begin  
              //保持传输状态  
              labProsStat.Caption   :=   '对方取消!';  
              TsCancle   ;  
              Exit;  
          end;  
   
          //按照指定位置传输文件  
          F_AFileStream.Seek(StrToInT(cmd),   soFromBeginning);   //转到文件流传输的位置  
          ASize   :=   Min(F_AFileStream.Size   -   F_AFileStream.Position,   RecvBufferSize);  
          //计算需要发送的大小,Min()函数在Math单元  
          OpenWriteBuffer;   //准备发送缓冲  
          WriteStream(F_AFileStream,   false,   false,   ASize);  
          //注意这个函数的参数。  
          CloseWriteBuffer;   //结束发送缓冲  
   
          //StatusBar1.SimpleText   :=   Format('当前传输位置%s/大小%d',   [cmd,   F_AFileStream.Size]);  
          labDoingStat.Caption   :=   Format('%s/%d',   [cmd,   F_AFileStream.Size]);  
          bsSkinGauge1.Value   :=   bsSkinGauge1.Value   +ASize;  
          Application.ProcessMessages;  
      end;  
  end;  
   
  procedure     TfrmNowChat.C_AcceptTranFile   ;  
  var  
      cmd:   string;  
      ASize,   TotalSize:   Int64;  
      AFileStream:   TFileStream;  
  begin  
      C_P2P.Host   :=FTranFile.IP   ;   //连接主机  
      C_P2P.Port   :=   9925   ;   //端口  
      C_P2P.Connect;   //连接  
      try  
          C_P2P.WriteLn('BEGIN');   //提示服务器开始接收  
          cmd   :=   C_P2P.ReadLn;  
          //以"|"符号分离文件名  
   
          SaveDialog1.FileName   :=   Copy(cmd,   Pos('|',   cmd)   +   1,   Length(cmd));  
          savedialog1.Filter   :=   ExtractFileExt(SaveDialog1.FileName)+'文件|*'+ExtractFileExt(SaveDialog1.FileName);  
           
          //   showmessage(SaveDialog1.FileName);  
          if   not   SaveDialog1.Execute   then  
          begin  
              C_P2P.WriteLn('CANCEL');   //告诉服务器取消  
              C_P2P.Disconnect;   //断开连接  
              exit;  
          end;  
   
          labDoingStat.Visible   :=   true   ;  
          bsSkinGauge1.Visible   :=   true   ;  
          labProsStat.Caption   :='正在接收文件...'   ;  
   
          TotalSize   :=   StrToInt(Copy(cmd,   0,   Pos('|',   cmd)   -   1));   //分离文件大小  
          bsSkinGauge1.MaxValue   :=     TotalSize   ;  
          bsSkinGauge1.Value   :=   0   ;  
   
          //建立文件流准备接收  
          AFileStream   :=   TFileStream.Create(SaveDialog1.FileName,   fmCreate);  
          try   //循环开始接受  
              repeat  
                  C_P2P.WriteLn(IntToStr(AFileStream.Size));//发送当前传输的位置  
                  ASize   :=   Min(TotalSize   -   AFileStream.Size,   C_P2P.RecvBufferSize);  
                  //选择剩余大小和缓冲区大小小的一个作为传输的大小  
                  C_P2P.ReadStream(AFileStream,   ASize);   //接收流  
                  bsSkinGauge1.Value   :=   bsSkinGauge1.Value   +   ASize   ;  
   
                  labDoingStat.Caption     :=   Format('%d/%d',   [AFileStream.Size,   TotalSize]);  
                  Application.ProcessMessages;  
              until   AFileStream.Size   =   TotalSize;   //大小一致了表示结束  
          finally  
              AFileStream.Free;   //释放文件流  
          end;  
          C_P2P.WriteLn('END');   //提示服务器传输完成  
          labProsStat.Caption   :=     '接收完成!';  
          bt1.Caption   :=   '打开'   ;  
          FTranFile.SaveFileName   :=   SaveDialog1.FileName   ;  
          TsCancle   ;  
          bt1.Visible   :=   true   ;  
          labSel.Visible   :=   true   ;  
      except  
          labProsStat.Caption   :=   '接收失败!';  
          TsCancle   ;  
      end;  
      C_P2P.Disconnect;  
  end;  
   
  procedure   TfrmNowChat.TsCancle   ;   //   清除相关变量  
  begin  
    //   取消传输,无论在未连接或是已连接的状态下  
          InitFtranFile   ;  
          labSel.Visible   :=   false   ;  
          bt1.Visible   :=   false   ;  
          bt2.Visible   :=   false   ;  
          labDoingStat.Visible   :=   false   ;  
          bsSkinGauge1.Visible   :=   false   ;  
   
          F_AFileStream.Free;   //释放文件流  
   
          if     C_P2P.Connected   then  
              C_P2P.Disconnect   ;  
          if     S_P2P.Active   then  
              S_P2P.Active   :=   false   ;       //   此句代码是想在传完后关闭服务器,以准备传其它文件,可是似乎会出错,我曾考虑过是不是应该在客户端断开连接后才关闭,将此句放在Disconnect中也会出错  
  end;  
 

查看回复

相关问题