udp文件传输(代码修改)

wqvic 2007-09-29 08:57:42
传输端:unit UnitClient;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient,
IdAntiFreezeBase, IdAntiFreeze, Gauges;


type
TFormClient = class(TForm)
Button1: TButton;
Edit1: TEdit;
OpenDialog1: TOpenDialog;
IdUDPClient1: TIdUDPClient;
Gauge1: TGauge;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
FormClient: TFormClient;

implementation

{$R *.dfm}

procedure TFormClient.Button1Click(Sender: TObject);
Var ReceivedString:String;
Mem:TFileStream;
P:Array[0..1023] of byte;
Posi,Len:Integer;
begin
if OpenDialog1.Execute then
begin
IdUDPClient1.Host:=Edit1.Text;
IdUDPClient1.Active:=True;
IdUDPClient1.Send('Send file:File Name:'+OpenDialog1.FileName);
ReceivedString:=IdUDPClient1.ReceiveString();
if UpperCase(ReceivedString)='RECIVED FILE NAME OK!' then
begin
Mem:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
try
Posi:=0;
IdUDPClient1.Send('Send File:File Length:'+IntToStr(Mem.Size));
ReceivedString:=IdUDPClient1.ReceiveString();
if UpperCase(ReceivedString)='RECIVED FILE LENGTH OK!' then
begin
While Posi<Mem.Size do
begin
Len:=1024;
if Mem.Size-Posi<1024 then
Len:=Mem.Size-Posi;
Mem.Read(P,Len);
IdUDPClient1.SendBuffer(P,Len);
Inc(Posi,Len);
Gauge1.Progress:=Round(Posi/Mem.Size*100);
ReceivedString:=IdUDPClient1.ReceiveString();
if UpperCase(ReceivedString)<>'RECIVED FILE PACKAGE OK!' then
Break;
Application.ProcessMessages;
end;
IdUDPClient1.Send('Send File:File End!');
end else
ShowMessage('Send file cancel!');
finally
Mem.Free;
end;
end;
end;
end;

end.
接受端:
unit UnitServer;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,IdBaseComponent, IdComponent, IdUDPBase, IdUDPServer,IdSocketHandle,
IdAntiFreezeBase, IdAntiFreeze, Gauges,RpRave;

type
TServerForm = class(TForm)
IdUDPServer1: TIdUDPServer;
procedure IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FileName:String;
FileSize:Integer;
Mem:TFileStream;
m:Tmemorystream;
{ Private declarations }
public
{ Public declarations }
end;

var
ServerForm: TServerForm;

implementation

{$R *.dfm}

procedure TServerForm.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
Var Str:String;
begin
AData.Seek(0,0);
SetLength(Str,AData.Size);
AData.Read(Str[1],AData.Size);
if Pos('Send file:File Name:',Str)>0 then
begin
Delete(Str,1,Length('Send file:File Name:'));
FileName:=Str;
Str:='Recived File Name OK!';
ABinding.SendTo(ABinding.PeerIP,ABinding.PeerPort,Str[1],Length(Str));
end else if Pos('Send File:File Length:',Str)>0 then
begin
Delete(Str,1,Length('Send File:File Length:'));
FileSize:=StrToIntDef(Str,0);
if not FileExists(FileName) then
Mem:=TFileStream.Create(FileName,fmOpenReadWrite or fmCreate)

else
Mem:=TFileStream.Create(FileName,fmOpenReadWrite);
Str:='Recived File Length OK!';
ABinding.SendTo(ABinding.PeerIP,ABinding.PeerPort,Str[1],Length(Str));
end else if Pos('Send File:File End!',Str)>0 then
begin
if Mem<>nil then
begin
Mem.Free;
Mem:=nil;
Str:='Recived File OK!';
ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, Str[1], Length(Str));
end;
FileName:='';
FileSize:=0;
end else
begin
Mem.Seek(0,2);
AData.Seek(0,0);
Mem.CopyFrom(AData,AData.Size);
m:=Tmemorystream.Create;
m.copyFrom(Mem,Mem.size);
m.SavetoFile('f:\'+FileName);
Str:='Recived File Package OK!';
ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, Str[1], Length(Str));
Application.ProcessMessages;
end;
end;

procedure TServerForm.FormCreate(Sender: TObject);
begin
IdUDPServer1.Active:=True;
FileName:='';
FileSize:=0;
Mem:=nil;
end;

procedure TServerForm.FormDestroy(Sender: TObject);
begin
if Mem<>nil then
Mem.Free;
end;

end.
无语法错误,但运行时,弹出ShowMessage('Send file cancel!');,我已确定是接受端有错误,大家帮忙改一下啊
...全文
196 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
happyct 2007-10-12
  • 打赏
  • 举报
回复
这样的代码,估计发送1M的文件都有可能失败。客户端一个while循环就不停调用IdUDPClient1.SendBuffer(P,Len); 怎么有这么轻松的事情啊。

最简单的校验方法:在IdUDPClient1.SendBuffer(P,Len); 后面sleep(1000)看看有没机会成功。

即使成功了,你的代码也是没任何用途的。
binghui123 2007-10-11
  • 打赏
  • 举报
回复
先检查下IP,端口吧
laowang2 2007-10-08
  • 打赏
  • 举报
回复
up
hongqi162 2007-10-08
  • 打赏
  • 举报
回复
丢包处理,校验包...............
fox1999 2007-10-08
  • 打赏
  • 举报
回复
UDP 啊 UDP

嘻嘻

應該先實現一個 UDP 的可靠傳輸協議才,再做傳文件。
UDP安全传输(完整源码) 大家都知道UDP比TCP好用发送速度快很多,程序写起来也简单的多,可缺点也同样明显UDP容易丢包,而且不能自动重发也不能自动组包没有数据安全机制,发的包不能超过2K(INDY,NMUDP等控件都是这样)否则就出错。 可很多需求中又需要发送大量数据包并且需要保证速度(如语音和视频通讯或者点对点点播服务。)而且有些重要的数据不允许丢包这个时候就需要安全UDP了。 有朋友可能会说那你干嘛不用TCP?TCP不就是安全的UDP吗? 主要因为 1、TCP无法很好的穿透NAT,来进行点对点通讯。 2、通讯过程中需要某些重要的命令不丢失,TCP需要首先建立连接,每个包都需要确认。这样发送速度会慢不少。 所以偶需要一个安全的UDP可以发送任意大小包,可以保证某些重要的包不会丢失,并且可以轻松穿透NAT来进行点对点通讯。 网上四处寻找未果SO自己动手写了一个。具有以下功能(本类是站在前人的肩膀上实现,基类为偶稍加修改过的NMUDP) 1、自动分包组包 2、支持一次性发送任意大小的包 3、支持安全控制 4、根据丢包率和网速度动态控制发包速度(因时间的局限此功能未很好的实现) 5、对于用户透明的接口(开发人员不用关心实现细节可以和使用其它UDP控件一样简单的使用本类)

1,594

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧