专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »p2p技术 » delphi编写服务:用Delphi编写点对点传文件程序 »正文

delphi编写服务:用Delphi编写点对点传文件程序

来源: 发布时间:星期三, 2008年12月17日 浏览:3次 评论:0
文章摘要:
   Delphi功能强大用Delphi写软件Software可以大大缩短软件Software开发周期本文介绍怎样用Delphi编写点对点传文件 
        

-------------------------------------------------------------------------
 
正文:   
用Delphi编写点对点传文件

  Delphi功能强大用Delphi写软件Software可以大大缩短软件Software开发周期有关点对点传文件基本思路就是个服务器软件Software个客户端软件Software使用同个端口待连接上以后客户端给服务器发送个请求包括待传文件文件名大小等如果服务器接受就开始传文件当然文件传输时候可以有两种模式ASCII码和Bin不过般通用Bin 就可以了基于上面讨论本来用Delphi4NMStrmNMStrmServ Control控件就可以完成但是我测试过了NMStrmControl控件对于较小文件还可以使用而且很方便但是如果文件大(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:eger;
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_QUERYServer接受到后发送MP_ACCEPT或MP_FEFUESE;
Client接受到MP_ACCEPT发送MP_FILEPROPERTYServer接受到后发送MP_NEXTWILLBEDATA;
Client接受到发送MP_NEXTWILLBEDATAServer接受到后发送MP_DATA;
Client接受到MP_DATA发送数据Server接受数据并发送MP_NEXTWILLBEDATA;
循环直到Client发送MP_OVER;
中间可以互相发送MP_CHAT+String;

Server:
放上以下Control控件:SaveDialog1,btnStartServer,
ss,(TServerSocket)

btnStartServer.OnClick(Sender:TObject);
begin
ss.Port:=2000;
ss.Open;
end;

ss.OnClientRead(Sender: TObject;Socket: TCustomWinSocket);
var
sTemp:;
bufRecv:Poer;
iRecvLength:eger;
begin
bReadText then
begin
sTemp:=Socket.ReceiveText;
sTemp[1] of
MP_QUERY:begin
//在这里拒绝
SaveDialog1.FileName:=Copy(sTemp,2,Length(STemp));
SaveDialog1.Execute then
begin
Socket.SendText(MP_ACCEPT);
fsRecv:=TFileStream.Create(SaveDialog1.FileName,fmCreate);
end
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 }
end
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:
放上以下Control控件: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
OpenDialog1.Execute then
Begin
cs.Socket.SendText(MP_QUERY+OpenDialog1.FileName);//FileSize???
end;
end;

cs.OnRead(Sender: TObject;Socket: TCustomWinSocket);
var
sTemp:;
bufSend:poer;
begin
sRecv:=Socket.ReceiveText;
Case sRecv[1] of
MP_REFUSE:ShowMessage('Fa,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);
(fsSend.Position+1+iBYTEPERSEND) < fsSend.Size then
begin
fsSend.Read(bufSend^,iBYTEPERSEND);
Socket.SendBuf(bufSend^,iBYTEPERSEND);
fsSend.Free;
end//普通发送大小为iBYTEPERSEND
begin
fsSend.Read(bufSend^,fsSend.Size-fsSend.Position-1);
Socket.SendBuf(bufSend^,fsSend.Size-fsSend.Position-1);
end;//最后次发送发送剩余数据
finally
FreeMem(bufSend,iBYTEPERSEND+1);
end;{of try}
end;
MP_ABORT:begin
//被取消了:(
fsSend.Free;
end;
end;{of }
end;


整理:
  加入判断优化把Server和Client联合在加入剩余时间进度显示做成能次传多个文件加入聊天功能就成了个很好点对点传文件

相关文章

读者评论

  • 共0条 分0页

发表评论

  • 昵称:
  • 内容: