这是在网上下载的,因为对网络传输文件这方面很菜,请各位高手帮帮忙,急着用,在线等!
先谢谢各位了!
\===============================================================================
procedure Tfrm_Server.IdTCPServer1Execute(AThread: TIdPeerThread);
var
  cmd: string; //接收到客户端的字符串信息
  ASize: Integer;
  count:integer; //需要传输的流大小
begin
  with AThread.Connection do //已经连街上的一个进程
  begin
    cmd := UpperCase(ReadLn); //客户端发送的命令字符串
    if cmd = 'BEGIN' then //开始传输
    begin
      //告诉远程传输文件的大小和文件名
      AFileStream := TFileStream.Create(filelist.Items.Strings[i], fmOpenRead);
      ProgressBar1.Max := AFileStream.Size;
      ProgressBar1.Position := 0;
      WriteLn(Format('%d|%s', [AFileStream.Size, filelist.Items.Strings[i]]));
      StatusBar1.SimpleText := '准备传输...';
      Exit;
    end;
    if cmd = 'END' then
    begin //传输完成
      Button3.Click;
      StatusBar1.SimpleText := '传输完成...';
      Exit;
    end;
    if cmd = 'CANCEL' then
    begin //传输取消
      StatusBar1.SimpleText := '传输取消...';
      //保持传输状态
      Exit;
    end;
    //按照指定位置传输文件
    AFileStream.Seek(StrToInT(cmd), soFromBeginning); //转到文件流传输的位置
    ASize := Min(AFileStream.Size - AFileStream.Position, RecvBufferSize);
    //计算需要发送的大小,Min()函数在Math单元
    OpenWriteBuffer; //准备发送缓冲
    WriteStream(AFileStream, false, false, ASize);
    //注意这个函数的参数。
    CloseWriteBuffer; //结束发送缓冲
    StatusBar1.SimpleText := Format('当前传输位置%s/大小%d', [cmd, AFileStream.Size]);
    ProgressBar1.Position := ProgressBar1.Position + ASize;
  end;
end;
=====================================================================================这个程序我想大家都熟悉,我测试的时候,只能和一个客户端发送,连接多个就行。

解决方案 »

  1.   

    try
    AThread.Synchronize(IncCon)
    finally
    AThread.Synchronize(DecCon)
    end;
      

  2.   

    结束后
    AThread.Connection.Disconnect
      

  3.   

    这是服务器端主程序,支持返回数据集,执行SQL语句等 
    procedure TfrmDM.tcpSvrExecute(AThread: TIdPeerThread);
    var
        APeerIP                   : string;
        APeerPort, iCmd           : Integer;
        iErrorCnt                 : Integer;begin    with AThread.Connection do
        try
            CoInitialize(nil);
            SvrParam.DataStream := TMemoryStream.Create;        CltParam.DataStream := TMemoryStream.Create;        AThread.Synchronize(IncCon);        APeerIP := AThread.Connection.Socket.Binding.PeerIP;
            APeerPort := AThread.Connection.Socket.Binding.PeerPort;        begin
                CltParam.Cmd := ReadInteger();
                CheckCmdPermission(iCmd);
                case CltParam.Cmd of
                    0:                                          //TestCon
                        begin
                            SvrParam.iResult := 0;
                            WriteInteger(SvrParam.iResult);
                        end;
                    1:                                          //GetData
                        begin
                            with cdsBill do
                            try
                                if Active then
                                    Active := False;
                                CltParam.SQL := ReadLn;
                                ShowMessage(CltParam.SQL);
                                CommandText := CltParam.SQL;
                                Active := True;
                                SvrParam.iResult := 0;
                                cdsCommon.SaveToStream(SvrParam.DataStream,dfBinary);
                                WriteInteger(SvrParam.iResult);
                                OpenWriteBuffer();
                                WriteStream(SvrParam.DataStream);
                                CloseWriteBuffer;
                            except
                                on E: Exception do
                                begin
                                    SvrParam.Info := '获取数据出错:' + E.Message + #13'语句:' + CltParam.SQL;
                                    SvrParam.iResult := -1;
                                    Writeln(SvrParam.Info);
                                end;
                            end;
                        end;
                    2:                                          //ExecSQL
                        begin
                            with cdsBill do
                            try
                                if Active then
                                    Active := False;
                                CommandText := CltParam.SQL;
                                Execute;
                                SvrParam.iResult := 0;
                                WriteInteger(SvrParam.iResult);
                                //WriteBuffer(SvrParam, SizeOf(SvrParam), True);
                            except
                                on E: Exception do
                                begin
                                    SvrParam.iResult := -1;
                                    SvrParam.Info := '执行语句出错:' + E.Message + #13'语句:' + CltParam.SQL;
                                    Writeln(SvrParam.Info);
                                end;
                            end;
                        end;
                    3:                                          //提交数据
                        begin
                            with qryBill do
                            try
                                if Active then
                                    Active := False;
                                SQL.Text := CltParam.SQL;
                                Active := True;
                                ReadStream(CltParam.DataStream, -1, True);
                                cdsCommon.LoadFromStream(CltParam.DataStream);
                                dspBill.ApplyUpdates(cdsCommon.Data, 0, iErrorCnt);
                            except
                                on E: Exception do
                                begin
                                    SvrParam.iResult := -1;
                                    SvrParam.Info := '提交数据出错:' + E.Message + #13'语句:' + CltParam.SQL;
                                    Writeln(SvrParam.Info);
                                end;
                            end;
                        end;
                end;
            end;
        finally
            try
                SvrParam.DataStream.Free;
                CltParam.DataStream.Free;
                AThread.Connection.Disconnect;
                AThread.Synchronize(DecCon);
                CoUninitialize;
            except        end;    end;
    end;
      

  4.   

    客户端的核心代码
    function TfrmDM._ExecSQL(SQL: string): Boolean;
    begin
        with tcpClt do
        begin
            _ReConnect;
            WriteInteger(9);
            WriteLn(SQL);
            Result := ReadInteger() = 1;
            if not Result then
                ShowMessage(ReadLn());
            Disconnect;
        end;end;function TfrmDM._GetData(SQL: string): OleVariant;
    var
        IsOK                      : Boolean;
    begin
        with tcpClt do
        begin
            _ReConnect;
            WriteInteger(10);
            WriteLn(SQL);
            IsOK := ReadInteger() = 1;
            if not IsOK then
                ShowMessage(ReadLn())
            else
            begin
                cdsCommon.Active := False;
                TmpStream := TMemoryStream.Create;
                ReadStream(TmpStream, -1, True);
                TmpStream.Seek(0, soFromBeginning);
                cdsCommon.LoadFromStream(TmpStream);
                Result := cdsCommon.Data;
                //Result := True;
                TmpStream.Free;
            end;
            Disconnect;
        end;
    end;
      

  5.   

    IncCon和DecCon是什么意思?是不是记录连接数?
      

  6.   

    这是客户端的程序
    ===============================================================
    var
      cmd: string;
      ASize, TotalSize: Int64;
      AFileStream: TFileStream;
      str:string;
      i,count:integer;
    begin
      bt_accept.Enabled:=false;
      bt_cancel.Enabled:=true;
      IdTCPClient1.Host := Edit1.Text; //连接主机
      IdTCPClient1.Port := StrToIntDef(Edit2.Text, 9925); //端口
      IdTCPClient1.Connect;//连接
      IdTCPClient1.WriteLn('BEGINA');
      count :=strtoint(IdTCPClient1.ReadLn);
      str:=edit3.Text+'\';
      i:=0;
      try
        repeat  //控制文件个数
        IdTCPClient1.WriteLn('BEGIN'); //提示服务器开始接收
        cmd := IdTCPClient1.ReadLn;
        TotalSize := StrToInt(Copy(cmd, 0, Pos('|', cmd) - 1));
        //建立文件流准备接收
        AFileStream := TFileStream.Create(str+Extractfilename(copy(cmd,pos('|',cmd)+1,length(cmd)-pos('|',cmd))), fmCreate);
        try //循环开始接受
          repeat
            IdTCPClient1.WriteLn(IntToStr(AFileStream.Size));//发送当前传输的位置
            ASize := Min(TotalSize - AFileStream.Size, IdTCPClient1.RecvBufferSize);
            //选择剩余大小和缓冲区大小小的一个作为传输的大小
            IdTCPClient1.ReadStream(AFileStream, ASize,false); //接收流
            StatusBar1.SimpleText := Format('当前传输位置%d/大小%d', [AFileStream.Size, TotalSize]);
            Application.ProcessMessages;
          until AFileStream.Size = TotalSize; //大小一致了表示结束
        finally
          AFileStream.Free; //释放文件流
        end;
        IdTCPClient1.WriteLn('ENDA'); //提示服务器传输完成
        i:=strtoint(IdTCPClient1.ReadLn);
        until i=count;
      except
        StatusBar1.SimpleText := '连接服务器失败或者对方已经中断传输!';
      end;
      IdTCPClient1.WriteLn('END');
      StatusBar1.SimpleText := '传输完成...';
      IdTCPClient1.Disconnect;
      bt_accept.Enabled:=true;
      bt_cancel.Enabled:=false;
    end;