程序是根据别人的示例自已修改完成的,运行他的文件传输程序没出错,但自已写的这个在传完文件以后,服务器端会出现“线程超时”、作些修改会出现关闭窗口时出现“无效窗口句柄”之类的错误,我对这方面完成是菜鸟,整了很久就是找不到原因,望高手们指点指点
以下是部分主要代码:
// 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;