Delphi UDp控件

DELPHI中有两个UDP控件:TIdUDPServer和TIdUDPClient控件,可用于传输UDP数据;用法都很简单,主要是一些细微的特性,弄清楚了对正确使用这两种控件有很大的好处;下面分别介绍:

一、              TIdUDPServer:代表一个UDP的服务端,接收UDP客户端发过来的数据;在FORM上放置一个TIdUDPServer控件,命名为UDPSvr,在FormCreate事件中编写如下代码:

 

    UDPSvr.Bindings.Add;

    UDPSvr.Bindings[0].IP := ‘192.168.2.117’;

 UDPSvr.Bindings[0].Port := 1812;

 UDPSvr.Active := True;

 

在UDPSvr控件的OnUDPRead事件中编写如下代码:

var

    Buffer: array[0..1024] of Char;

    iSize: integer;

    sData: string;

begin

      ZeroMemory(@Buffer,sizeof(Buffer));

 

      iSize := AData.Size;

      if iSize > 1024 then

      begin

        iSize := 1024;

      end;

 

      AData.Seek(0,soFromBeginning);

      iSize := AData.Read(Buffer,iSize);

      。。。。。{对接收数据的处理}

end;

 

这样就完成了一个可以接收数据的UDP应用程序;

其实TIdUDPServer有发送数据的方法:Send和SendBuffer,是继承自TIdUPDBase,所以只要利用TIdUDPServer控件就可完成数据的收发,在FORM上添加一个Tbutton控件,在Click事件中添加如下代码;

var

  Buffer: array[0..1024] of Char;

  sText: string;

  iLen: integer;

begin

  sText := ‘12345678’

  ZeroMemory(@Buffer,sizeof(Buffer));

  StrPCopy(Buffer,sText);

  iLen := Length(sText);

 

UDPSvr.SendBuffer(‘192.168.2.117’,1814,Buffer,iLen);

end;

 

            这样就可以向另一UDP应用程序发送数据;

 

          一个TIdUDPServer控件可以打开多个端口,如下的代码打开了两个端口:

            UDPSvr.Bindings.Add;

            UDPSvr.Bindings[0].IP := GetLocalIP;

            UDPSvr.Bindings[0].Port := 1812;

 

            UDPSvr.Bindings.Add;

            UDPSvr.Bindings[1].IP := GetLocalIP;

            UDPSvr.Bindings[1].Port := 1813;

 

            UDPSvr.Active := True;

      

             当打开多个端口时,发送数据是从哪个端口发送出去呢?根据测试结果是:最近收到数据的那个端口;如果还没有收到过数据,则为Bindings[0].Port;

      

            在接收数据的事件中,有一个TidSocketHandle类型的参数:Abinding;这个参数有两对属性:

            IP 、Port:代表本地IP地址和端口;

            PeerIP、PeerPort:代表远端IP地址和端口;

            其中PeerIP、PeerPort在交复发送数据的UDP应用中是很有用的,因为UDP服务端可以向PeerIP和PeerPort回应数据,而不用再去设置UDP客户端的IP地址和端口号(这种方法应用不当,会产生问题,下面会说到);

 

二、              TIdUDPClient:代表一个UDP的客户端,专门用于发送UDP数据,不能接收数据,因为没有相应的事件和方法;前面已经说过,利用TIdUDPServer控件就可以完成UDP数据的收发,所以一直怀疑TIdUDPClient控件存在的必要性;除非有一个UDP的客户端只发送数据,而从不接收数据,这样的客户端应该很少;后来我想,可能可以用TIdUDPClient控件来分担TIdUDPServer控件的负载,在一个需要收发大量UDP数据的服务端中,TIdUDPServer控件只接收数据,另外专门用一个TIdUDPClient控件发送数据,也许可以提高应用程序的性能(没有经过验证);利用TIdUDPClient发送数据有两种方式:

1、  利用TIdUDPClient控件本身的Send和SendBuffer方法,这时需要设置Host和Port属性,在FORM上放置一个TIdUDPClient控件,命名为:UDPClt;分别设置Host和Port属性值为:192.168.2.117和1814;再编写如下代码:

var

  Buffer: array[0..1024] of Char;

  sText: string;

  iLen: integer;

begin

  sText := ‘12345678’;

 

  ZeroMemory(@Buffer,sizeof(Buffer));

  StrPCopy(Buffer,sText);

  iLen := Length(sText);

 

  UDPClt.SendBuffer(Buffer,iLen);

   end;

 

2、  不需要设置Host和Port属性,而直接利用从TIdUPDBase继承来的Send和SendBuffer方法,也可发送数据,代码如下所示:

 

UDPClt.SendBuffer(‘192.168.2.117’,1814,Buffer,iLen);

 

 TIdUDPClient控件发送数据时是通过哪个端口发出去的呢?根据测试的结果:是随机的;这样就给上面说过的UDP服务端可以向PeerIP和PeerPort回应数据造成了麻烦,也就是说如果UDP服务端收到的数据是通过TIdUDPClient控件发过来的,就不能通过PeerIP和PeerPort回应回去,而应设定客户端的IP地址和端口号;在具体应用中是哪种情况,要根据测试结果而定。

我自己折腾半天,总是报错,原来是没有添加udp控件,这两个控件在Indy Server标签下,郁闷啊。折腾一天,原来这原因。

我自己

股票,证券等,用这个来发布行情数据,刷刷的。 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、付费专栏及课程。

余额充值