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
相关文章
读者评论
发表评论 |