关于DELPHI IOCP的问题 小弟以纠结10多天无赖唯有请教各位大虾(愿意帮忙的有一点点RMB谢礼)

ye429333234 2012-12-05 02:45:57
这个IOCP控件使用的是
http://download.csdn.net/detail/foreverhero/2267433
这个大大的
目前小弟面临几个问题,用这个控件开发的目的是和网页上的FLASH的SOCKET交互
要实现的功能:
1:FLASH请求 获取当前在这个位置的用户列表//比如http://www.xxx.com/news/
那么当用户进入这个页面时候,就获取当前在这个页面的所有用户的用户名,然后通知当前已经在的用户,有新用户进来了

我的想法是当打开这个网页加载完FLASH以后 FLASH就连接这个DELPHI的服务器,连接成功以后 发送当前所在位置和用户名的包,比如定义为setloact|name|loact(位置如"http://www.xxx.com/news/
")然后DELPHI的服务端把这个SOCKET的指定添加进一个链表(这个链表类是我以前写的双向链表)
然后用一个FOR循环遍历出当前已经在这个位置的用户的SOCKET 通知他们有新用户到了发送"add|name(新来用户的名字)"
然后遍历出所有当前已经在这里的用户的名字发送给新来的这个SOCKET包为"addlist|name1|name2|name3|..."


那么这个DELPHI的服务端的处理应该怎么设计呢?小弟是小白,只是以前接触过DELPHI而已
当服务器接收到包后,我想应该不会直接在控件的dzIocp1Recv事件里面直接调用处理函数吧
我现在是什么方式多试过了 比如(在事件里直接调用处理函数,在事件里创建线程调用处理函数等,始终不完美)
只有创建线程调用处理函数要稍微好一点,但始终有这样那样的问题.

特别是通知其他在线用户有新用户来了的时候 FOR循环给他们发送消息的时候 用异步发生好像有问题


哎 我也不知道应该怎样描述了 ,不知道各位大大明白我的意思没有,我就想请教各位大大,我现在就是想用这个IOCP控件实现 获取用户列表以及通知他们有新的人进来了这种应该怎么处理才合理和高效!

自己开始弄的时候看起来觉得很简单的 但是做起来就发现这样那样的问题 ,我觉得问题主要应该是在IOCP的事件处理是多线程的吧,然后就是通知已经在线的用户新用户来的时候,是不是不能在FOR循环里面发送消息呢?

首先申明一下 咱并不想做拿来主义者,但确实对软年开发的很多东西都不懂,也不是专业做开发,现在开始自学 要搞懂IOCP以及一些底层的东西 估计最少也要一年半载以上了(咱只是一个写DIV+CSS的....)

如果谁有兴趣的可以去上面的连接下一个这个控件里面有他的DEMO 帮我在这个DEMO的TCPSERVER里面加上我上面描述的处理框架 小弟除了答谢论坛的分以外还额外答谢50RMB(如果嫌弃的别噴,咱只想说一句,钱虽然不多,但这是咱的一点心意,其中包含的感激之情不是用RMB能衡量的)
我的QQ:627464 有兴趣的可以加我 我可以详细描述一下问题!
...全文
384 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
SQLDebug_Fan 2012-12-10
  • 打赏
  • 举报
回复
IOCP是异步通知机制,用Timer是不合适的。
ZyxIp 2012-12-10
  • 打赏
  • 举报
回复
每次添加的时候就让执行线程启动, FTSTRINGLIST.add(XX); 处理线程.Resume;
ye429333234 2012-12-09
  • 打赏
  • 举报
回复
以我现在的水平 我能想到的就只有用一个TIMER来一直循环检查 FTSTRINGLIST.count,但我觉得这么做应该是不对的 不合理的....
ye429333234 2012-12-09
  • 打赏
  • 举报
回复
7楼的大大 我明白你的意思 而且我也是这么认为的 但是关键就在于,比如我把收到数据存进TSRINGLIST里面,那么我只是在Recv事件里面写上一句,FTSTRINGLIST.add(XX); 如何让处理线程当FTSTRINGLIST.count大于0的时候 切大于2的时候 就启动2个线程,如果等于1就启动1个线程来读取TStringList的数据,处理一条删除一条,如果没有的时候,处理线程就挂起....关键就在于如何通知线程有数据了 开始工作 ....能不能大概说一下有什么方式 或者说给个简单 的几句例子呢?谢谢啦
ye429333234 2012-12-09
  • 打赏
  • 举报
回复
谢谢楼上的
萨弗迪发个 2012-12-08
  • 打赏
  • 举报
回复
http://www.2ccc.com/article.asp?articleid=6002 自己看吧
haitao 2012-12-08
  • 打赏
  • 举报
回复
iocp是为效率优化过的socket实现 你初次实现socket服务,还是先用普通的socket服务控件实现,这样容易把精力放在业务上
SQLDebug_Fan 2012-12-08
  • 打赏
  • 举报
回复
王婆卖瓜,我前段时间刚好开源了一个IOCP的代码,有完整的说明和测试,地址:http://blog.csdn.net/sqldebug_fan/article/details/7881793,供楼主参考。
ZyxIp 2012-12-08
  • 打赏
  • 举报
回复
先创建一个列表来保存收到的数据,Recv事件中只是负责将数据保存到这个列表中。 另外在创建几个处理线程,从列表中读取数据,做对应的业务处理。 注意,不是线程越多越好,100个连接有一两个业务处理线程就可以了。 这个列表的读和写用临界区保护就可以了。
ye429333234 2012-12-08
  • 打赏
  • 举报
回复
谢谢各位的回答,非常感谢~!现在大体的问题是解决,至少同时100个连接和刷新相应的在线用户列表问题是解决,但是优化问题又来了,现在的执行效率我感觉很低了,因为我还是在数据到达的Recv事件里面创建线程来执行的处理函数,当同时请求量大的时候,程序貌似就开始有点"反应迟钝",我想应该是处理函数里面又加了临界,所以可能有N多个线程都执行到临界那里挂起等待造成的吧,哎 ....又不知道应该怎么办了
蓝色光芒 2012-12-07
  • 打赏
  • 举报
回复
顶起来...
ZyxIp 2012-12-07
  • 打赏
  • 举报
回复
不管你用的是什么,你只有一个列表来保存连接上来的 SOCKET ,然后你为每个SOCKET 创建一个接收缓冲区,每个SOCKET 有数据来时就保存在对应的缓冲区中。当SOCKET断开时就从列表中删除,这个列表做的添加和删除要做成多线程同步的。 然后你单独开一个线程,它的功能就是循环检查这个列表,处理每个缓冲区中的数据,包括给发送数据。发送数据用 try except 保护,因为有可能在发送的时候出错。在线程的循环中每处理一个SOCKET用 Sleep(0);来暂停一下。
ye429333234 2012-12-07
  • 打赏
  • 举报
回复
没有人愿意说一下吗?
完成端口通讯服务器(IOCP Socket Server)设计 (六)功能强大的IOCP Socket Servre模块例程源码 Copyright © 2009 代码客(卢益贵)版权所有 QQ:48092788 源码博客:http://blog.csdn.net/guestcode 一、声明 版权声明: 1、通讯模块代码版权归作者所有; 2、未经许可不得全部或部分用于任何项目开发; 3、未经许可不得部分修改后再利用源码。 免责声明: 1、 由于设计缺陷或其它Bug造成的后果,作者不承担责任; 2、未经许可的使用作者不提供任何技术支持服务。 权利和义务: 1、任何获得源码并发现Bug的个人或单位均有义务向作者反映; 2、作者保留追究侵权者法律责任的权利。 二、开发背景 部分代码由前项目分离而来,尚未有应用考验,但对于初学者学习和进阶有很大帮助。性能上尚未有定论,但应该不会令你失望。 三、功能说明 1、可以关闭Socket的Buffer; 2、可以关闭MTU(不等待MTU满才发送); 3、可以多IP或多端口监听; 4、可以重用socket(主动关闭除外); 5、可以0缓冲接收(Socket的Buffe = 0时,避免过多的锁定内存页); 6、可以0缓冲连接(客户端仅连接,不一定立即发数据); 7、可以条件编译: a、是否使用内核Singly-linked lists; b、是否使用处理线程(工作线程和处理线程分开); c、是否使用内核锁来同步链表。 8、可以实现集群服务器模式的通讯(有客户端socket); 9、可以单独设置每个连接的Data项来实现连接和Usernfo的关联; 10、每个线程有OnBegin和OnEnd,用于设置线程独立的对象(数据库会话对象); 11、可以提供详细的运行情况,便于了解IOCP下的机制,以及进行调试分析; 12、可以发起巨量连接和数据(需要硬件配置来支持)。
最近有项目要做一个高性能网络服务器,决定下功夫搞定完成端口(IOCP),最终花了一个星期终于把它弄清楚了,并用C++写了一个版本,效率很不错。 但,从项目的总体需求来考虑,最终决定上.net平台,因此又花了一天一夜弄出了一个C#版,在这与大家分享。 一些心得体会: 1、在C#中,不用去面对完成端口的操作系统内核对象,Microsoft已经为我们提供了SocketAsyncEventArgs类,它封装了IOCP的使用。请参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socketasynceventargs.aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1。 2、我的SocketAsyncEventArgsPool类使用List对象来存储对客户端来通信的SocketAsyncEventArgs对象,它相当于直接使用内核对象时的IoContext。我这样设计比用堆栈来实现的好处理是,我可以在SocketAsyncEventArgsPool池中找到任何一个与服务器连接的客户,主动向它发信息。而用堆栈来实现的话,要主动给客户发信息,则还要设计一个结构来存储已连接上服务器的客户。 3、对每一个客户端不管还发送还是接收,我使用同一个SocketAsyncEventArgs对象,对每一个客户端来说,通信是同步进行的,也就是说服务器高度保证同一个客户连接上要么在投递发送请求,并等待;或者是在投递接收请求,等待中。本例只做echo服务器,还未考虑由服务器主动向客户发送信息。 4、SocketAsyncEventArgs的UserToken被直接设定为被接受的客户端Socket。 5、没有使用BufferManager 类,因为我在初始化时给每一个SocketAsyncEventArgsPool中的对象分配一个缓冲区,发送时使用Arrary.Copy来进行字符拷贝,不去改变缓冲区的位置,只改变使用的长度,因此在下次投递接收请求时恢复缓冲区长度就可以了!如果要主动给客户发信息的话,可以new一个SocketAsyncEventArgs对象,或者在初始化中建立几个来专门用于主动发送信息,因为这种需求一般是进行信息群发,建立一个对象可以用于很多次信息发送,总体来看,这种花销不大,还减去了字符拷贝和消耗。 6、测试结果:(在我的笔记本上时行的,我的本本是T420 I7 8G内存) 100客户 100,000(十万次)不间断的发送接收数据(发送和接收之间没有Sleep,就一个一循环,不断的发送与接收) 耗时3004.6325 秒完成 总共 10,000,000 一千万次访问 平均每分完成 199,691.6 次发送与接收 平均每秒完成 3,328.2 次发送与接收 整个运行过程中,内存消耗在开始两三分种后就保持稳定不再增涨。 看了一下对每个客户端的延迟最多不超过2秒。

1,593

社区成员

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

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