IDUdpServer研究心得
IDUdpServer研究心得
Indy10中的控件IDUdpServer使用方便,比之Indy9有较大的改动,不过使用的时候一定要先弄清楚它的基本工作流程哦,不然会带来很大的麻烦,一下是本人经过查看源代码及N多测试得出的一些心得:
(1) 使用多线程
把控件的ThreadedEvent设置为true后控件事件就会在绑定线程内执行了,这个多线程给人的感觉好像是每个连接创建一个线程,其实不是这样的。Udp是没有连接概念的,而事实上是每个绑定套接字(Binding:TIdSocketHandle)绑定创建后都会开启一个线程,这个线程专门处理当前绑定套接字的收发工作。
(2) OnUDPRead事件AThread、ABinding直接的关系
上面我们也说到了每个绑定套接字(Binding:TIdSocketHandle)绑定创建后都会开启一个线程,这样就是说这两个参数是一一对应,每个AThread的线程工作期间只处理当前的绑定套接字的收发。
(3) Dll内使用IdUdpServer无法执行OnUDPRead事件?
答案其实是否定的,如果我们把ThreadedEvent设置为true的话在dll内OnUDPRead事件是可以正常激发的,我们可以看看一下代码:
procedure TIdUDPListenerThread.Run;
var
PeerIP: string;
PeerPort : TIdPort;
ByteCount: Integer;
begin
if FBinding.Select(AcceptWait) then try
// Doublecheck to see if we've been stopped
// Depending on timing - may not reach here if it is in ancestor run when thread is stopped
if not Stopped then begin
SetLength(FBuffer, FServer.BufferSize);
ByteCount := GStack.ReceiveFrom(FBinding.Handle, FBuffer, PeerIP, PeerPort, FBinding.IPVersion);
SetLength(FBuffer, ByteCount);
FBinding.SetPeer(PeerIP, PeerPort, FBinding.IPVersion);
if FServer.ThreadedEvent then begin //备注(1)
UDPRead;
end else begin
Synchronize(UDPRead);
end;
end;
except
// exceptions should be ignored so that other clients can be served in case of a DOS attack
on E : Exception do
begin
FCurrentException := E.Message;
FCurrentExceptionClass := E.ClassType;
if FServer.ThreadedEvent then begin
UDPException;
end else begin
Synchronize(UDPException);
end;
end;
end;
end;
这段代码是套接字工作线程的主要实现代码,从备注(1)加粗处我们可以看到如果IdUdpServer的属性ThreadedEvent为false时会使用到了Synchronize进行主线程同步,而Synchronize方法是无法在dll应用程序内正常使用的,所以大家使用时候要注意这点。
(4) Server.ReceiveBuffer、Binding.Receive方法使用注意事项
请看看一下代码:
if UDPController.Bindings[0].Readable(20000) then begin
try
SetLength(FBuffer,2048);
RecvLen:=UDPController.Bindings[0].Receive(FBuffer);
BytesToRaw(FBuffer,_LogonDataPackage,SizeOf(_LogonDataPackage));
//Result := Binding.RecvFrom(ABuffer, VPeerIP, VPeerPort, AIPVersion);
AThread.UDPRead; //备注1
except
// exceptions should be ignored so that other clients can be served in case of a DOS attack
on E : Exception do
begin
AThread.UDPException; //备注2
end;
end;
end;
end
else begin
RecvLen:=0;
end;
注意备注部分,这样是不恰当的,地方AThread.UDPRead时,读的数据却是上次的数据,不是我们预想的结果,故需使用以下代码:
if UDPController.Bindings[0].Readable(20000) then begin
try
SetLength(FBuffer,2048);
RecvLen:=UDPController.Bindings[0]. RecvFrom(FBuffer,CurrPeerIP,CUrrPeerPort, UDPController.Bindings[0].IPVersion);
// 设置当前Peer,很重要
UDPController.Bindings[0].SetPeer(CurrPeerIP,CUrrPeerPort,Binding.IPVersion);
BytesToRaw(FBuffer,_LogonDataPackage,SizeOf(_LogonDataPackage));
AThread.Server.OnUDPRead(AThread,FBuffer,AThread.Binding);
except
// exceptions should be ignored so that other clients can be served in case of a DOS attack
on E : Exception do
begin
AThread.Server.OnUDPException(AThread,AThread.Binding,E.Message,E.ClassType);
end;
end;
end;
end
else begin
RecvLen:=0;
end;
(5) 在绑定线程外不宜使用Server.ReceiveBuffer、Binding.Receive等方法接收数据报
绑定线程外接收数据报如接收到不是自己所需数据时,很难把此次数据拷挂到绑定线程内激发OnUDPRead,使得OnUDPRead事件只能响应在绑定线程外,这样给程序设计和跟踪都带来了不小的麻烦,因此如在绑定线程外实现接收数据报效果最好建立自己的接收队列,使用轮训接收数据报队列的方式实现。
转载于:https://www.cnblogs.com/zhmore/archive/2010/08/29/1811921.html
IDUdpServer研究心得相关推荐
- Python字符串的encode与decode研究心得乱码问题解决方法
Python字符串的encode与decode研究心得乱码问题解决方法 为什么Python使用过程中会出现各式各样的乱码问题,明明是中文字符却显示成"\xe4\xb8\xad\xe6\x96 ...
- 杭州SEO大熊:百度分享插件的SEO研究心得
杭州SEO大熊:百度分享插件的SEO研究心得 百度分享插件对seo网站优化有影响吗? 至少目前看来基本没有什么影响,不过百度既然推出它并且 显示在搜索结果页面里以大拇指图标推荐形式呈现给大家必然不是一 ...
- 研究心得:调研文献“快而全“的三步
前言 本人研究心得体会,仅做参考和讨论,本人为计算机工科方向,其他学科领域可能无法参考 调研文献一直是一件让人很头疼的事情,尤其是我们刚接触一个陌生的领域的时候,我们对其知之甚少,而恰好组里又没有师兄 ...
- 深度学习之父Geoffrey Hinton:我的五十年深度学习生涯与研究心得
来源:数据派THU & 机器学习初学者 作者:王菁 林亦霖 沈佳丽 程浩源 许菡如 胡燕君 贾川 编辑:AiCharm [AiCharm导读]Geoffrey Hinton被公认是人工智能的教 ...
- Minecraft TrMenu 菜单插件 研究心得
目录 导读 链接 函数 材质参数化 全局变量操作 待更新- 导读 本文主要是对 TrMenu 插件部分用法解释 为了方便我个人查阅 啊哈哈哈 主要使用 TrMenu v3 版本作为演示 文章内容仅为个 ...
- ocos2d-x Win32下的节点缩放原理研究心得
[2.1.0]Cocos2d-x Win32下的节点缩放原理研究心得 [复制链接] 火星熊猫 19 主题 2 听众 489 积分 版主 收听TA 发消息 电梯直达 楼主 发表于 2013- ...
- 图灵奖得主Geoffrey Hinton:我的五十年深度学习生涯与研究心得
来源:数据派THU & 机器学习初学者 作者:王菁 林亦霖 沈佳丽 程浩源 许菡如 胡燕君 贾川 编辑:新智元 他从未正式上过计算机课程,本科在剑桥大学读的是生理学和物理学,期间曾转向哲学,但 ...
- CQR_Encode 二维码研究心得
最新因为工作需要,研究了一下二维码,QRCode,在这里记录下心得.第一次写博客,加上水平不高,如果有写的不好的地方,还请指教. 主要是基于 Psytec Inc. ,一个日本的公司开发的一款 QR_ ...
- 自己对Delphi中使用正则表达式的研究心得
在 Delphi 中使用正则表达式, 目前 PerlRegEx 应该是首选, 在此分享一下自己的一些心得体会. 官方网站: http://www.regular-expressions.info/de ...
最新文章
- ubuntu dpkg initramfs-tools错误的解决方法
- 19课 Vue第二节
- LaTex 插入数学公式
- acrgis api for javaScript需要对Dojo了解多少?
- 不用任何插件实现 WordPress 的彩色标签云
- ubuntu mysql集群搭建_ubuntu server部署mysql集群
- 一文看尽中亦科技EVO-ITSM 3.0新品发布会
- python基础教程之pymongo库
- 为什么要选择crm私有化布署?
- 如何向小白程序员解释区块链
- OBLOG4.5 商业SQL版 漏洞解析
- 注解处理器(Annoation Processor)
- BackupManagerService分析 基于Android 8.0
- 微信小程序-枯木学习笔记2-我的第一个小程序
- 营养不良和口服万古霉素对人体肠道菌群和营养吸收的影响
- IE浏览器代理服务器总是自动打开,取消勾选隔一会又会打开
- 工作9年程序员面试华为要薪1万,华为员工:公司没这么低工资的岗.
- SMBIOS介绍(1):概述
- 主宾国 guest of honor
- 简易商品展示HTML+CSS
热门文章
- 从Scala2.13.0开始废弃了一些方法
- 安卓学习笔记07:事件处理、窗口跳转与传递数据
- SSM框架笔记13:Spring MVC基础
- 【多题合集】线段覆盖1、2、3
- 1.极限——例子_2
- bzoj3192 [JLOI2013]删除物品 树状数组
- bzoj1996 [Hnoi2010]chorus 合唱队 区间dp
- java辐射汉化_新研究:低强度环境辐射足以导致量子比特退相干
- Intel超线程技术 Hyper-Threading Technology (6) - 后期增强(Nehalem/Haswell/Skylake)
- Intel(R) 处理器产品架构/微架构对照表