发送数据时有Sendln,SendBuf,SendStream。接收数据时有Receiveln,ReceiveBuf,当时我很奇怪为什么没有ReceiveStream。因为很自然的想到是对应关系的。但当时我不知道,发数据时是一小段一小段地发的
看看SendStream代码:
- function TBaseSocket.SendStream(AStream: TStream): Integer;
- var
- BufLen: Integer;
- Buffer: array[0..511] of Byte;
- begin
- Result := 0;
- if Assigned(AStream) then
- begin
- repeat
- BufLen := AStream.Read(Buffer, SizeOf(Buffer));
- until (BufLen = 0) or (SendBuf(Buffer, BufLen) = SOCKET_ERROR);
- end;
- end;
从以上代码可看到,SendStream一次最多发送512字节的内容,所以,我们这接收端循环用ReceiveBuf接收就可以了。不用像以前那样写得又复杂乱。
发送端(Client)代码:
- unit Unit1;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls, Sockets;
-
- type
- TForm1 = class(TForm)
- tcpclnt1: TTcpClient;
- btn1: TButton;
- procedure btn1Click(Sender: TObject);
- private
-
- public
-
- end;
-
- var
- Form1: TForm1;
-
- implementation
-
- {$R *.dfm}
-
- procedure TForm1.btn1Click(Sender: TObject);
- var
- f : TFileStream;
- i : Integer;
- fn : string;
- begin
-
- for i := 1 to 11 do
- begin
- tcpclnt1.Connect;
- fn := ‘a‘ + IntToStr(i) + ‘.rar‘;
- f := TFileStream.Create(‘d:/send/‘ + fn,fmOpenRead);
- tcpclnt1.Sendln(fn);
- tcpclnt1.Sendln(IntToStr(f.Size));
- tcpclnt1.SendStream(f);
- f.Free;
- tcpclnt1.Disconnect;
- end;
- end;
-
- end.
接收端(Server)代码:
- unit Unit1;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, Sockets;
-
- type
- TForm1 = class(TForm)
- tcpsrvr1: TTcpServer;
- procedure FormActivate(Sender: TObject);
- procedure tcpsrvr1Accept(Sender: TObject;
- ClientSocket: TCustomIpClient);
- private
-
- public
-
- end;
-
- var
- Form1: TForm1;
-
- implementation
-
- {$R *.dfm}
-
- procedure TForm1.FormActivate(Sender: TObject);
- begin
- tcpsrvr1.Open;
- end;
-
- procedure TForm1.tcpsrvr1Accept(Sender: TObject;
- ClientSocket: TCustomIpClient);
- var
- f : TFileStream;
- iFileSize : Integer;
- iTotalRec : Integer;
- iacRec : Integer;
- pbuf : Pointer;
- i : Integer;
- fn : string;
- begin
- GetMem(pbuf,512);
- try
- iTotalRec := 0;
- fn := ClientSocket.Receiveln;
- iFileSize := StrToInt(ClientSocket.Receiveln);
- f := TFileStream.Create(‘d:/rec/‘+ fn,fmCreate);
- try
-
- while iTotalRec < iFileSize do
- begin
- iacRec := ClientSocket.ReceiveBuf(pbuf^,512);
- if iacRec = -1 then
- Break;
- f.Write(pbuf^,iacRec);
- Inc(iTotalRec,iacRec);
- end;
- finally
- f.Free;
- end;
- finally
- FreeMem(pbuf);
- end;
- end;
-
- end.