用Delphi编写点对点传文件程序

来源:互联网 发布:淘宝男装外套 编辑:程序博客网 时间:2024/05/26 08:43

======================================================
注:本文源代码点此下载
======================================================

文章摘要:

delphi功能强大,用delphi写软件,可以大大缩短软件的开发周期。本文介绍怎样用delphi编写点对点传文件程序。

正文:

用delphi编写点对点传文件程序

delphi功能强大,用delphi写软件,可以大大缩短软件的开发周期。关于点对点传文件的基本思路,就是一个服务器软件,一个客户端软件,使用同一个端口,待连接上以后,客户端给服务器发送一个请求,包括待传的文件的文件名,大小等,如果服务器接受,就开始传文件。当然,文件传输的时候可以有两种模式,ascii码和bin,不过一般通用bin 就可以了。基于上面的讨论,本来用delphi4的nmstrm,nmstrmserv 控件就可以完成,但是我测试过了,nmstrm控件对于较小的文件还可以使用,而且很方便,但是如果文件一大(1m)就会出错。所以接下来我们利用delphi中tserversocket和tclientsocket写这个程序由于以太包大小的限制以及delphisocket的处理机制(delphi中,当你用一个socket发送一个较大的stream,接受方会激发多次onread事件,delphi她只保证多次onread事件中每次数据的完整,而不会自己收集数据并返回给用户。所以不要以为你把待传文件在一个socket中send一次,另一个中recv一次就可以了。你必须自己收集数据或自己定义协议。),所以我们采用自定义协议的方法。定义协议的规范方法是利用record end。如:

tmyfileprotocol=record

ssendtype=(st_query,st_refuse,st_data,st_abort,...);

ilength:integer;

bufsend:buffer;

end;

我曾试过这个办法,但失败了,而且我一直认为我的方法是正确的,但程序一直编译通不过,估计是delphi有问题:) 所以我在下列的范例程序中利用另外一种办法。socket 类中有两属性receivetext和receivebuf,在一个onread事件中,只能使用一次该两属性,所以我们可以利用一个全程变量来保存是该读text还是buf,也就是说读一次text,再都一次buf,这就模拟了tmyfileprotocol。

开始程序:

写一个最简单的,主要用于讲解方法。

定义协议:

const

mp_query ='1';

mp_refuse ='2';

mp_accept ='3';

mp_nextwillbedata='4';

mp_data ='5';

mp_abort ='6';

mp_over ='7';

mp_chat ='8';

协议简介:

首先由client发送mp_query,server接受到后发送mp_accept或mp_fefuese;

client接受到mp_accept发送mp_fileproperty,server接受到后发送mp_nextwillbedata;

client接受到发送mp_nextwillbedata,server接受到后发送mp_data;

client接受到mp_data,发送数据,server接受数据,并发送mp_nextwillbedata;

循环,直到client发送mp_over;

中间可以互相发送mp_chat+string;

server程序:

放上以下控件:savedialog1,btnstartserver,

ss,(tserversocket)

btnstartserver.onclick(sender:tobject);

begin

ss.port:=2000;

ss.open;

end;

ss.onclientread(sender: tobject;socket: tcustomwinsocket);

var

stemp:string;

bufrecv:pointer;

irecvlength:integer;

begin

if breadtext then

begin

stemp:=socket.receivetext;

case stemp[1] of

mp_query:begin

//在这里拒绝

savedialog1.filename:=copy(stemp,2,length(stemp));

if savedialog1.execute then

begin

socket.sendtext(mp_accept);

fsrecv:=tfilestream.create(savedialog1.filename,fmcreate);

end

else socket.sendtext(mp_refuse+'去死');

end;

mp_fileproperty:begin

//要发送strtoint(copy(stemp,2,length(stemp))) 次

//时间进度显示。。。

socket.sendtext(mp_nextwillbedata);

end;

mp_nextwillbedata:begin

socket.sendtext(mp_data);

breadtext:=false;

end;

mp_end:begin

fsrecv.free

breadtext:=true;

end;

mp_abort:begin

fsrecv.free;

breadtext:=true;

end;

mp_chat:begin

//chat msg

end;

end;{of case}

end

else begin

try

getmem(bufrecv,2000);//2000 must >ibytesend

socket.receivebuf(bufrecv^,irecvlength);

fsrecv.writebuffer(bufrecv^,irecvlength);

finally

freemem(bufrecv,2000);

end;{of try}

breadtext:=true;

socket.sendtext(mp_nextwillbedata);

end;

end;

client程序:

放上以下控件:edtipaddress,opendialog1,btnconnect,btnsendfile,

cs. (tclientsocket)

btnconnect.onclick(sender:tobject);

begin

cs.address:=edtipaddress.text;

cs.port:=2000;

cs.connect;

end;

btnsendfile.onclick(sender:tobject);

begin

if opendialog1.execute then

begin

cs.socket.sendtext(mp_query+opendialog1.filename);//filesize???

end;

end;

cs.onread(sender: tobject;socket: tcustomwinsocket);

var

stemp:string;

bufsend:pointer;

begin

srecv:=socket.receivetext;

case srecv[1] of

mp_refuse:showmessage('faint,be refused!');

mp_accept:begin

fssend:=tfilestream.create(opendialog1.filename,fmopen);

//ibytepersend是个常量,每次发送包的大小。

socket.sendtext(mp_fileproperty+trunc(fssend.size/ibytepersend)+1);

end;

mp_nextwillbedata:begin

socket.sendtext(mp_nextwillbedata);

end;

mp_data:begin

try

getmem(bufsend,ibytepersend+1);

if (fssend.position+1+ibytepersend) 整理程序:

加入错误判断,优化程序,把server和client联合在一起,加入剩余时间进度显示,做成能一次传多个文件,加入聊天功能,就成了一个很好的点对点传文件的程序。

trackback: http://tb.blog.csdn.net/trackback.aspx?postid=3507

绿色通道:好文要顶关注我收藏该文与我联系


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
原创粉丝点击