indy 10终于随着delphi2005发布了,不过indy套件在我的印象中总是复杂并且bug不断,说实话,不是看在他一整套组件的面子上,我还是喜欢vcl原生的socket组件,简洁,清晰.indy9发展到了indy10几乎完全不兼容,可叹啊.言归正传.在使用idtcpserver组件的时候发现了他的漏洞,他的onconnec,onexecute,ondisconnect等事件是在其他线程中执行的,通常情况下这没有问题,但是在特殊的情况下会造成问题,如果其他部分的程序写得有问题就会出现漏洞.
问题出在这里,listview是一个windows的标准组件,释放他的一个item是通过消息完成的,也就是说,我在ondisconnect中在一个非主线程的线程中向主线程的窗口发送消息并且等待返回.而此时主线程在干嘛呢?因为是主线程触发的disconnect,所以他在等待这个端口的服务线程挂起,这样就发生死锁,问题在于,主线程的等待服务线程挂起的处理代码不当,它理论上应该在等待同时处理消息.原代码如下所示 【程序编程相关:QQ窗体自动隐藏效果探究 】
我发现的漏洞是这样的,我在ondisconnect事件中释放一个listview的一个对应的item,也就是,一个客户端离开的时候,界面上的listview对应的项目删除.正常情况没有任何问题,但是,如果不断开连接直接关闭程序就会死掉,事实上我在程序中form的closequery事件中作了处理,在这个事件中我关闭连接,但是,没有效果,只有在程序中手动的点鼠标关闭才不会死掉,问题出在哪里? 【推荐阅读:读书笔记:Delphi5 开发人员指南 】
【扩展信息:扫雷外挂的设计与实现(五) 】procedure tidschedulerofthread.terminateyarn(ayarn: tidyarn);
var lyarn: tidyarnofthread; begin lyarn := tidyarnofthread(ayarn); if lyarn.thread.suspended then begin //判断是否挂起了,挂起了才释放线程 // if suspended, was created but never started // ie waiting on connection accept lyarn.thread.free; freeandnil(lyarn); end else begin // is already running and will free itself ... 下一页