您的位置:首页 > 理论基础 > 计算机网络

用TTcpClient和TTcpServer进行文件的传输

2017-04-14 22:13 483 查看
发送数据时有Sendln,SendBuf,SendStream。接收数据时有Receiveln,ReceiveBuf,当时我很奇怪为什么没有ReceiveStream。因为很自然的想到是对应关系的。但当时我不知道,发数据时是一小段一小段地发的

看看SendStream代码:

[delphi] view plain copy

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)代码:

[delphi] view plain copy

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

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);

var

f : TFileStream;//文件流

i : Integer;

fn : string;//文件名

begin

{用for循环是实现发送多个文件,如果只是发送一个文件,不用循环}

for i := 1 to 11 do

begin

tcpclnt1.Connect; //连接服务端,我把TTcpClient的BlockMode设为bmBlocking

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)代码:

[delphi] view plain copy

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

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormActivate(Sender: TObject);

begin

tcpsrvr1.Open; //在OnActive事件中启动TCPServer的监听

end;

procedure TForm1.tcpsrvr1Accept(Sender: TObject;

ClientSocket: TCustomIpClient);

var

f : TFileStream; //文件流

iFileSize : Integer; //文件大小

iTotalRec : Integer; //总接收到的字节数,用来和文件大小比较,如果比文件大小的值要小,就还要继续接收

iacRec : Integer; //每一次ReceiveBuf实际接收到的字节数

pbuf : Pointer; //缓存指针

i : Integer;

fn : string; //文件名

begin

GetMem(pbuf,512); //我们一次最多也读取512字节

try

iTotalRec := 0; //先把总接收到的字节数置零

fn := ClientSocket.Receiveln; //接收文件名

iFileSize := StrToInt(ClientSocket.Receiveln); //接收文件大小,接收到的字符串,要转成integer

f := TFileStream.Create('d:/rec/'+ fn,fmCreate);//创建文件

try

{如果接收到的总字节数小于文件总字节数且实际接收字节数不为-1就一直循环接收}

while iTotalRec < iFileSize do

begin

iacRec := ClientSocket.ReceiveBuf(pbuf^,512);//一次接收512字节

if iacRec = -1 then

Break;//如果实际接收字节数是-1表示出错了,退出循环(应该写个log,或作出错处理什么的)

f.Write(pbuf^,iacRec);//把接收到的数据写到文件流中

Inc(iTotalRec,iacRec);//叠加接收到的总字节数

end;

finally

f.Free; //释放流

end;

finally

FreeMem(pbuf);//释放内存

end;

end;

end.


http://blog.csdn.net/zang141588761/article/details/52288692
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐