【原创】基于UDP的可靠数据连接方式UDT C++Builder6下编译成功包【原创】

huzhangyou 2007-12-02 03:54:15
还是前面那个朋友公司的问题,可能在VS2003以及更高版本使用太成功顺利的感觉,要在C++Builder6下面编译,还费了偶不少时间哈!

需要注意的地方大概说一下,需要源码的可以联系我QQ或者MSN或者同我Email,我会在看到消息以后立刻发送给你。

1:需要在编译的头部定义
#define WIN32
2:部分#elif的地方需要注释并截取windows平台的代码

3:生成的lib文件需要包含使用,同时更加需要处理的是 将obj文件进行包含进工程,这是在我实在解决不了了以后,突然打开lib文件,发现里面仅仅是一堆obj文件,才想到的方法,真的是机缘巧合啊。

4:需要#pragma link "Ws2_32.lib"

最后编译就OK了


代码下载:

http://www.libing.net.cn/read.php/1449.htm
...全文
551 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
huzhangyou 2007-12-03
  • 打赏
  • 举报
回复
to DoorKey:

非常感谢你的回复

我想你还没有注意这段小小代码的设计方案:

注意里面的 TempListData: TList;
临界区只是进入到这里 就将所有的数据Copy出来了
然后立刻释放锁
然后线程去处理这个 TempListData: TList;

另外你所说的方案其实并没有考虑到过多的线程切换所带来的代价

当然可以采取线程池来处理
而你想想一下,如果队列里面 10条数据
只处理一个数据的话,这样锁的概率岂不是更大
期望继续跟帖

wg961423 2007-12-03
  • 打赏
  • 举报
回复
收藏学习中。。。。。。
DoorKey 2007-12-03
  • 打赏
  • 举报
回复
我觉得你的处理线程设计得有问题,你的代码如下:
procedure ExecuteCenterData.ExecuteData;
var
i,j:integer;
TempListData: TList;
begin
TempListData := TList.Create;
frm_Main.CS.Enter;//注意
for i:=0 to frm_Main.CenterMsg.Count-1 do
begin
TempListData.Add(frm_Main.CenterMsg[i]);
end;
frm_Main.CenterMsg.Clear;
frm_Main.CS.Leave;

for j:=0 to TempListData.Count-1 do
begin
//TempListData.Add(frm_Main.CenterMsg[i]);
//fuck now TempListData[j]
end;
end;
你看一下你的代码,是在一个处理线程一次取下所有已经接收到数据,这当然会造成这个处理线程长时间临界区,
我觉得应该开多个线程而一个处理线程一次只处理一个接收到的数据。这样可能相对会好一点。
僵哥 2007-12-03
  • 打赏
  • 举报
回复
> 据称在Windows的高版本当中有一个SinglyLinkedList,比较高效,具体的没有加以测试评估。

如果使用这个的话 是不是线程就不需要同步了?
================================
这个就是为提高线程访问共享数据的同步提升效率而设置的所谓“原子级”操作。
i_love_pc 2007-12-03
  • 打赏
  • 举报
回复
板凳听课中...
huzhangyou 2007-12-03
  • 打赏
  • 举报
回复
>曾经看MSDN的时候,好象有见到过一个未来版本(即Windows Vista/2008以后),有基于原子操作的队列,实现也是基于SinglyLinkedList.
这个我也听过

不过没有看到过相关资料

>也可以考虑使用TLS(Thread-local storage )。

我先看看TLS的资料,再来讨论 非常感谢

>据称在Windows的高版本当中有一个SinglyLinkedList,比较高效,具体的没有加以测试评估。

如果使用这个的话 是不是线程就不需要同步了?
僵哥 2007-12-03
  • 打赏
  • 举报
回复
曾经看MSDN的时候,好象有见到过一个未来版本(即Windows Vista/2008以后),有基于原子操作的队列,实现也是基于SinglyLinkedList.
僵哥 2007-12-03
  • 打赏
  • 举报
回复
除了资源池以及IOCP 有没有别的折中的方法
=========================
据称在Windows的高版本当中有一个SinglyLinkedList,比较高效,具体的没有加以测试评估。但是比较可惜,它是一个堆栈的模式,并且MSDN说是只在内核当中应用。相关的函数有:InitializeSListHead(初始化),InterlockedPushEntrySList(压栈),InterlockedPopEntrySList(出栈),InterlockedFlushSList(刷新)。

其他的暂时想不到更好的了。或者不需要多线程的同步,也可以考虑使用TLS(Thread-local storage )。这里要提一下的是,完成端口也可以当成是一个队列来用(FIFO),并且暂时也没有发现什么太大的瓶颈(当然不可能没有消耗)。
UDX协议 2007-12-03
  • 打赏
  • 举报
回复
udt在公网上效率不高。目前最新版本。
huzhangyou 2007-12-03
  • 打赏
  • 举报
回复
资源池

改天实现一个资源池发上来

IOCP实现倒不是难事
但是同样的问题 也还是数据进入临界区的问题

或许资源池 可以解决 具体的方案还要数据测试

to DoorKey:
>我们的目标是尽最大可能减少UDP监听线程被Enter挂起的次数。线程适量多是没有问题的。

这个我想你没有经过压力测试,我是专门做服务器开发的,问题你倒是也提出来了 只是解决方案没有

期待

to unsigned: 除了资源池以及IOCP 有没有别的折中的方法
僵哥 2007-12-03
  • 打赏
  • 举报
回复
比如“环”元素为N,设当前节点下标为Index,那么各线程索引到的节点就是:ThreadedIndex = InterlockedExchange(Index,(Index+1) % N),如果需要退节点就是:InterlockedExchange(Index,(Index+(N-1)) % N)。

对于这种分散同步的方法,个人觉得对于资源池也是一个比较好的方法。仅仅只是增加部分内存的消耗。在长期使用之后,基本上可以达到平衡。
僵哥 2007-12-03
  • 打赏
  • 举报
回复
普通的UDP包 能继续讨论一下如何避免吗?
=======================
UDP我也只是这两周才开始做个小小的东西。以前是同事写的,使用的是Indy,方法是开双线程。不过我所需要的业务比较简单,也不希望让它占用两它线程那么浪费。刚开始的时候,只是决定采用单线程非阻塞的方式,虽然没有进行验证,但是要么线程一直占用CPU资源,不断的检索收发(不习惯使用select)。基于应用当中众多地方都是采用IOCP来管理,顺便把很多任务的调度都放在其中。所以干脆就使用IOCP(我的应用比较简单,都是单包应用,不需要考虑拼接)。同时开多个WSARecvFrom,然后就不断地收发完事。多个WSARecvFrom轮询,基本上不会由于本地线程的“碰车”而导致丢包。

另外,最近在考虑一个问题就是类似于TimerWheel模式的同步管理。采用“同步环”,进行多路同步。比如说把“同步环”设置为N个“环节点”,然后根据不同的数据导入采用环境索引,从而可以达到多节点分散同步,来减少线程碰撞。
QSmile 2007-12-03
  • 打赏
  • 举报
回复
樓主,能不能把 UDT 做成標准 DLL 在 Delphi 下使用?
DoorKey 2007-12-03
  • 打赏
  • 举报
回复
你的代码在Enter后是用循环来把所有数据加到新创建的TempListData。哪怕就10条,这个也是很影响的。(我曾经用程序测试过)
frm_Main.CS.Enter;//注意
for i:=0 to frm_Main.CenterMsg.Count-1 do
begin
TempListData.Add(frm_Main.CenterMsg[i]);
end;
frm_Main.CenterMsg.Clear;
frm_Main.CS.Leave;

我们的目标是尽最大可能减少UDP监听线程被Enter挂起的次数。线程适量多是没有问题的。
huzhangyou 2007-12-02
  • 打赏
  • 举报
回复
to unsigned:

兄长对网络方面比较熟悉,这个问题你继续

我说一下我的问题:

我的问题并不是UDT引起的
而是普通的UDP引起的

就是普通的UDP包 能继续讨论一下如何避免吗?


UDP Socket 等待数据有数据来临 TCriticalSection CS;
CS-> Enter
//这里面把数据压入了List
CS-> Leave

这个List是全局的数据 在一个线程里面进行处理同样也是CS-> Enter
CS-> Leave
问题就出来了

当这个数据在线程里面Enter的时候 UDP Socket接收到数据 发现CS没有被释放
这个数据是不是直接被丢弃了
前提用的是Indy的UDP Socket
僵哥 2007-12-02
  • 打赏
  • 举报
回复
UDT的本意是为大文件传输而设计,而并不是高并发,所以存在并发阻塞,也在所难免。
huzhangyou 2007-12-02
  • 打赏
  • 举报
回复

有道理
只是 这个足够快只是一个概念词
如何保证呢?

怎么设计一个足够快的Cache
难道也设计一个Cache池?
ly_liuyang 2007-12-02
  • 打赏
  • 举报
回复
"数据都投递到了,而我数据队列忙,导致丢失"这也是UDP本来的缺陷
UDP Socket获取数据后,立即投递到应用层,不管应用层是否处理完,系统是不管的
所以你需要另外的Cache机制,这个Cache要足够快来处理,而且尽可能不存在阻塞
huzhangyou 2007-12-02
  • 打赏
  • 举报
回复
等待高人。。。
继续
huzhangyou 2007-12-02
  • 打赏
  • 举报
回复

constructor TThreadList.Create;
begin
inherited Create;
InitializeCriticalSection(FLock);
FList := TList.Create;
FDuplicates := dupIgnore;
end;

destructor TThreadList.Destroy;
begin
LockList; // Make sure nobody else is inside the list.
try
FList.Free;
inherited Destroy;
finally
UnlockList;
DeleteCriticalSection(FLock);
end;
end;

procedure TThreadList.Add(Item: Pointer);
begin
LockList;
try
if (Duplicates = dupAccept) or
(FList.IndexOf(Item) = -1) then
FList.Add(Item)
else if Duplicates = dupError then
FList.Error(@SDuplicateItem, Integer(Item));
finally
UnlockList;
end;
end;

procedure TThreadList.Clear;
begin
LockList;
try
FList.Clear;
finally
UnlockList;
end;
end;

function TThreadList.LockList: TList;
begin
EnterCriticalSection(FLock);
Result := FList;
end;

procedure TThreadList.Remove(Item: Pointer);
begin
LockList;
try
FList.Remove(Item);
finally
UnlockList;
end;
end;

procedure TThreadList.UnlockList;
begin
LeaveCriticalSection(FLock);
end;

{ TInterfaceList }

constructor TInterfaceList.Create;
begin
inherited Create;
FList := TThreadList.Create;
end;

destructor TInterfaceList.Destroy;
begin
Clear;
FList.Free;
inherited Destroy;
end;


上面的代码为系统的代码
从代码可以得知 也是通过TCriticalSection方式实现的
当然是TRTLCriticalSection
加载更多回复(9)
特等奖标准成品论文(Word无水印纯净版) 硬核结构:全文含完整的摘要、问题重述与分析、模型假设、符号说明、模型建立与求解、灵敏度分析及结论。 即插即用:排版严格遵循官方规范,逻辑严密。拿到手即可作为绝佳的高分参考模板,稍作替换与个性化润色即可极速完稿,彻底解决写论文难的痛点。 双源硬核解题代码(Python与MATLAB双版本) 拒绝假代码:提供底层逻辑清晰、模块化设计的全套可运行源码。 全流程覆盖:涵盖从前期数据清洗预处理,到中期核心数学模型训练,再到后期启发式算法寻优。 傻瓜式运行:代码自带详尽的逐行中文注释,并支持一键生成高质量结果可视化图表,编程小白也能轻松复现与二次开发。 全量数据与结果展示表 所有中间处理数据、模型输出参数以及最终结论,均已精细整理成高质量表格。直观呈现性能评估指标与多模型对比分析,可直接作为论文正文或附件使用,极大提升学术说服力。 独家硬核思路解析 深入浅出剖析出题人意图,详细拆解每一小问的数学本质与底层逻辑,让你不仅知其然更知其所以然。 【四大核心产品优势】 高效实用:所有代码与论文均经过严格测试,确保结果精准无误、完全可复现,省去熬夜试错的时间。 全栈覆盖:从思路分析到跑出结果,再到写出高质量论文,提供一站式全流程资料矩阵。 排版辅助:资料内提供专业的论文排版一键转换工具与官方标准模板,告别格式调整的繁琐。 持续迭代:网盘直发,开赛后资料库将持续滚动更新,所有用户均可免费同步获取最新。 【适用人群】 想要打破建模瓶颈的参赛队长与主攻手;急需高质量底层代码的编程小白;目标直指特等奖需要高分模板对标的精英团队。
内容概要:本文围绕分布式光伏储能系统的优化配置方法展开,重点基于Matlab代码实现系统建模与仿真分析,涵盖光伏出力不确定性、负荷响应特性及储能充放电行为的综合建模。通过引入改进鲸鱼优化算法、粒子群算法等智能优化算法,解决系统容量配置、能量管理策略与多目标优化调度等问题,旨在提升系统运行效率、降低能耗成本并延长设备使用寿命。研究内容还括并网与离网模式下的经济性对比、微电网能量优化管理、储能配置方案评估,并提供完整的Matlab代码、数据集及论文撰写模板,支持科研成果的高效产出。; 适合人群:具备电力系统、新能源技术或自动化等相关专业背景,熟悉Matlab/Simulink仿真环境的研究生、科研人员及工程技术人员;特别适用于计划撰写EI/SCI期刊论文的高层次研究人员。; 使用场景及目标:①开展分布式光伏储能系统配置的科研课题与学术论文撰写;②实现微电网能量管理系统的设计与优化调度算法验证;③掌握基于Matlab的多目标优化建模方法,提升在新能源系统规划与运行领域的科研创新能力。; 阅读建议:建议结合提供的Matlab代码与Simulink模型进行动手实践,重点关注优化算法的实现逻辑与参数调优过程,按照文档目录循序渐进学习,构建完整的知识体系,并参考配套论文模板完成研究成果的规范化输出。

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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