我在serversocket只接收到客户端传来文件的一半大小不到,我又不知道咋回事
哪位大哥能帮我改下面的代码?const
  sendbyte =1000;  //每次发送包的大小clientsocketButton.onclick
var
 tsfile :tfilestream;
  buff  :pointer;
begin
  tsfile:=tfilestream.create('g:\demo.dat' ,fmopenread);
  repeat
    getmem(buff ,1001);
    if (tsfile.position+sendbyte)<tsfile.size  then
      begin
       tsfile.readbuff(Buff^,sendbyte);
       clientsocket.socket.sendbuff(buff^,sendbyte);  
      end
    else  
    begin  //拷内剩下的字节
     tsfile.readbuff(buff^,tsfile.size-tsfile.position);
     clientsocket.socket.sendbuff(buff^,tsfile.size-tsfile.position);
    end;
    freemem(buff,1001);
  until tsfile.position>=tsfile.size;
  tsfile.free
end;serversocket.onread
var
  buff :pointer;
begin
  getmem(buff,1001);
  socket.recvdbuff( buff^,sendbyte);
  streamfile.writebuff(buff^,sendbyte); //写入新文件
  freemem(buff,1001);
   //不知道应该咱改,最后一次好像不到1000字节end;

解决方案 »

  1.   

    serversocket.onread中的socket.recvdbuff( buff^,sendbyte);
    一句有问题。
    recvdbuff方法不保证能完整收到数据。
    我也用tcpclient和tcpserver写了一个类似软件,
    这样进行了处理:
    procedure TForm1.TcpServer1Accept(Sender: TObject;
      ClientSocket: TCustomIpClient);
    var
        flen ,rlen,position :  integer;
        recthread : TClientDataThread;
    begin
       if savedialog1.Execute then
             begin
             position:=0;
             clientsocket.ReceiveBuf(flen,sizeof(integer));
             recthread:=TClientDataThread.Create(true);
             recthread.fname:=savedialog1.FileName;
             recthread.flength:=flen;
             setlength(recthread.buf,flen);
             rlen:=ClientSocket.ReceiveBuf(recthread.buf[position],flen);
             position:=rlen+position;
             while rlen<flen do
                 begin
                 flen:=flen-rlen;
                 rlen:=clientsocket.ReceiveBuf(recthread.buf[position],flen);
                 position:=rlen+position;
                 end;
             recthread.Resume;
             end;
    end;
    完整代码如下:
    unit mainform;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Sockets, ComCtrls;type
      TForm1 = class(TForm)
        TcpClient1: TTcpClient;
        TcpServer1: TTcpServer;
        btnchg: TButton;
        Edit1: TEdit;
        edtRemoteHost: TEdit;
        edtRemotePort: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        btnsel: TButton;
        btnsnd: TButton;
        OpenDialog1: TOpenDialog;
        ProgressBar1: TProgressBar;
        SaveDialog1: TSaveDialog;
        procedure btnchgClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure btnselClick(Sender: TObject);
        procedure btnsndClick(Sender: TObject);
        procedure TcpServer1Accept(Sender: TObject;
          ClientSocket: TCustomIpClient);
      private
        { Private declarations }
        sndfilename  :  string;
      public
        { Public declarations }
      end;TClientDataThread = class(TThread)
        buf : array of byte;
        fname : string;
        flength : integer;
        constructor Create(CreateSuspended: Boolean);
        procedure Execute; override;
        procedure acceptfile;
         procedure Terminate;
        end;
    var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btnchgClick(Sender: TObject);
    begin
      tcpserver1.LocalPort:=edit1.Text;
      //tcpserver1.Listening:=true;   错误:  listening 是只读属性
      tcpserver1.Active:=true;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      sndfilename:='';
      form1.btnchg.Click;
    end;procedure TForm1.btnselClick(Sender: TObject);
    begin
      if opendialog1.Execute then
         sndfilename:=opendialog1.FileName;
    end;procedure TForm1.btnsndClick(Sender: TObject);
    var
         sfile  :  Tfilestream;
         filebuf : array of byte;
         filelength : integer;
    begin
      TcpClient1.RemoteHost := edtRemoteHost.Text;
      TcpClient1.RemotePort := edtRemotePort.Text;
      try
        if TcpClient1.Connect then
           begin
           sfile := tfilestream.Create(sndfilename,fmOpenRead);
           filelength:=sfile.Size ;
           setlength(filebuf,filelength+sizeof(integer));
          // filebuf:=pchar(allocmem(filelength+1));
          copymemory(filebuf,@filelength,sizeof(integer));
           sfile.Read(filebuf[sizeof(integer)],filelength);
          // filebuf[filelength+1]:=#0;
           sfile.Free;
           tcpclient1.SendBuf(filebuf[0],filelength+sizeof(integer));       end;
      finally
        TcpClient1.Disconnect;  end;
    end;{ TClientDataThread }procedure TClientDataThread.acceptfile;
    var
        fstream : Tfilestream;
    begin
       fstream:=tfilestream.Create(fname,fmcreate);
       fstream.Write(buf[0],flength);
       //fstream.Free;
    end;constructor TClientDataThread.Create(CreateSuspended: Boolean);
    begin
      inherited Create(CreateSuspended);
      FreeOnTerminate := true;
    end;procedure TClientDataThread.Execute;
    begin
      Synchronize(acceptfile);
    end;procedure TForm1.TcpServer1Accept(Sender: TObject;
      ClientSocket: TCustomIpClient);
    var
        flen ,rlen,position :  integer;
        recthread : TClientDataThread;
    begin
       if savedialog1.Execute then
             begin
             position:=0;
             //flen  := ClientSocket.BytesReceived ;
             clientsocket.ReceiveBuf(flen,sizeof(integer));
             recthread:=TClientDataThread.Create(true);
             recthread.fname:=savedialog1.FileName;
             recthread.flength:=flen;
             setlength(recthread.buf,flen);
            // recthread.buf:=pchar(allocmem(flen+1));
             rlen:=ClientSocket.ReceiveBuf(recthread.buf[position],flen);
             position:=rlen+position;
             while rlen<flen do
                 begin
                 flen:=flen-rlen;
                 rlen:=clientsocket.ReceiveBuf(recthread.buf[position],flen);
                 position:=rlen+position;
                 end;
             recthread.Resume;
             end;
    end;procedure TClientDataThread.Terminate;
    begin
       inherited;
    end;end.
      

  2.   

    你用的是非阻塞SOCKET方式,failer(独败)贴出来的是阻塞方式的。其实只要小小改一下就行了。。serversocket.onread
    var
      buff :pointer;
      n:integer;
    begin
      getmem(buff,1001);
      repeat
        n:=socket.recvdbuff( buff^,1000);//一定要取得实际读得的大小。。
        if n>0 then
        begin
          streamfile.writebuff(buff^,n); //写入新文件
        end
      until n<1000 ;  freemem(buff,1001);
    end;