Delphi中UDP协议通讯

Delphi中UDP协议通讯

先在type域中定义Record(未压缩)或Packed Rcord(压缩包)结构体,再用Indy的idUDPclient和idUDPServer分别负责发送和接收

如:注意每定义一节都接一个End;表示定义完其中一个,末尾不再加其他end;

{------------------------------------------------------}

type

tcGetUserBuffer = record
ID: Integer;
Size: Integer;
nType: DWORD; //Dword是无符号32位长整型,直接赋十进制数就可以了。
UserID: Dword;
IMEI: array [0..23] of char;
end;

tcGetUserNextBuffer = record
ID: integer;
size: integer;
nTtype: Dword;
IP: Dword;
Port: Dword;

info:array[0..9] of char; //这是定义一个十位的Char类型,在VC++中用Char name[10][定义

end;

{------------------------------------------------------}

上面只是定义了结构体,在使用时,需要注意的是:这只是一个结构,也就是一个类似于骨架的东西,没有实际意义,在给结构体赋值(一般称为填包)时,发出去和接收到的只是一堆数组,所以发送和接收时都需要用到定义的结构体。另外有些结构体为了方便,也可以像下面这样定义包头和包体,在接收处理时就会更方便、灵活一些。

type

Head = record

ID:integer;

Command:Dword;

end;

tGetInfo = record
userID: Dword;

end;

tGetInfoBuffer = record;

tHead: Head;

tBody:tGetInfo;

end;

像上面这样就定义了一个多维的结构体,其实到最后还是一样的数组发送和接收。

现在看看怎么发送:

Procedure Button1_click();

var

Buffer: tcGetUserBuffer;

begin

Buffer.ID=1234;

Buffer.nType=4;

... //结构一般要填满,这里省略

IDudpClient.SendBuffer(Buffer,Sizeof(tcGetUserBuffer)) //Sizeof一定要获得结构体的长度才行。

end;

以上是发送一个包,现在看看接收包和处理包。

procedure TForm1.IdUS1UDPRead(Sender: TObject; AData: TBytes;
ABinding: TIdSocketHandle); //注意,D7中要手动uses[IdSocketHandle]这个类,自己加在上面。
Var

Buffer1: tcGetUserBuffer;

Buffer2: tcGetUserNextBuffer ;

//依此类推,把要用到的变量名Buffer[n]和结构体都定义好,以区分比较复杂的包类型。

begin

//下面是根据包长度判断不同的包,来分别处理它们。
if length(AData)=sizeof(tcGetUserBuffer) then
begin

Adata.read(Buffer1,Adata.size);

showmessage(inttostr(Buffer1.ID));

Abinding.sendto(Abinding.peerip,Abinding.peerport,data,sizeof(dataRecord)) //这句的意思是向发数据的IP和端口号回复数据,这个data和dataRecord没有填包和定义,实际应用时,要注意。
end;
if length(AData)=sizeof(tcGetUserNextBuffer) then
begin

Adata.read(Buffer2,Adata.size);

showmessage(inttostr(Buffer1.ID));

end;
end;

**指针的用法也很关键的

比如UDPserver收到数据包也可以用一个字节数组来接收

Var

ArrByte: Array [0..64000] of byte;

begin

Adata.readBuffer(ArrByte,Adata.size);

end;

在使用时,则要用到各种指针操作命令了。

Arrbyte[0]就是从数组的第一个字节。

读取字符串时,要用到Pchar(@ArrByte[0]),注意只用了一个@,后面不接^。

读取数字时,用Pinteger(@ArrByte[0])^,这里用了两个符号,要注意它们的 位置。

注意:上面两例都是读数组的所有字节,所以,在实际用时,可能要用到这个命令

Move(ArrByte1,ArrByte2,tSize)

两个数组没有定义,后面的大小要看实际情况。

Move是一个很好用的东东,有时可能需要从结构Record复制到数组,也是一样的:

Move(Buffer1,ArrByte,tSize)

这样就可以了。

其实Delphi在实际处理中还有很多东西,以后慢慢写,比如用线程发包、收包处理,包频繁发送,量大的还要做发送队列用到很多控件和类,以后再写啦。

股票,证券等,用这个来发布行情数据,刷刷的。 UDP通信的优势 速度比TCP快。 UDP通信的缺点 一旦UDP包过大的话,也能正常工作。只是优势就丢失了。 idUdpClient 主要用于发送udp请求,在接收udp响应的时候是同步的,所以一定要设置超时,否则的话程序容易死。 idUpdServer 即能用于发送udp数据包,也能用于接收udp数据包。但是设计的主要目的还是用于收到udp数据包之后给于反馈。 UDP包的大小问题 资料1:以太网的MTU是1500字节,IP包头占20个字节,UDP首部占8个字节,也就是说实际数据应该小于1472字节. 资料2:鉴于Internet上的标准MTU值为576字节,所以我建议在进行Internet的UDP编程时.最好将UDP的数据长度控件在548字节(576-8-20)以内. 测试结果: 0-548字节:会完美的展现UDP协议的优势(速度刷刷的)。 大于1472字节以后的话,也可以正常执行。你会见识到什么叫做不可靠的信道(经过测试90%以上还是成功的,只是速度慢了很多)。 数据包大于2K速度明显变慢了;数据包大于3K,成功率60%到80%;数据包大于4k,成功率20%以下。 结论: 1.UDP协议还是比较可靠的。使用它能充分挖掘速度的潜力。通常大部分请求和相应都在548以下,小部分请求超过548。 2.548字节,可以存储274个汉字呢。比手机短信都长。你传什么那么大? 3.尤其是双方都在修改数据,需要实施数据实时同步的时候。修改量都比较小,用udp再合适不过了。 客户端的阻塞式响应不太理想 可以采用的办法是双方都开UDP服务器来接受。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值