mmz-asio4delphi死链接的解决办法
最近一段时间,因为忙于网络的项目,特意到网上找了些例子,特意花时间研究了一下马敏钊写的 mmz-asio4delphi 感觉很好用,不过深入研究之后,发现一个问题。
马大的这个代码,会产生死链接。
try
if TAsioClient(FClientLst.Objects[i]).Socketptr > 0 then begin
Asio_closesocket(TAsioClient(FClientLst.Objects[i]).Socketptr);
TAsioClient(FClientLst.Objects[i]).Socketptr := 0;
end;
//Asio_DisConnedCallback(integer(TAsioClient(FClientLst.Objects[i])));
except
end;
这是TAsioSvr.CheckDeadClients中的一段代码,可能跟原版的有点区别,不过大体在这。可以看到,上面的代码中,如果socketptr不为0则调用asio_closesocket函数关闭,
然后直接给Socketptr赋值为0。但运行后发现,虽然程序中socketptr已经赋值为0,并且对应的客户端也已经删除,但在Windows中,该链接还是存在,当初占用的端口依旧被占用。
在程序中的体现就是:显示AsioSvr.FClientLst.Count 和 AsioSvr.FDeadClients.Count 的数量,要远远小于,从360看到的该程序占用链接的数量,说明其中很多死链接存在。
以下是asio_closesocket的C++代码:
DllExport int Asio_closesocket(session * isocket)
{
//isocket->userdata=0;//不允许再触发
try
{
isocket->deadtime=GetTickCount();
isocket->socket().cancel();
boost::system::error_code ignored_ec;
isocket->socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
isocket->socket().close(); }
catch(...)
{}
//EnterCriticalSection(&criCounter);
//deadlist.push_back(isocket);
//LeaveCriticalSection(&criCounter); //delete isocket;
return ;
}
因为不怎么懂C++,所以不知道该怎么改。那怎么解决死链接杀不掉的问题呢?
有的大大说,只要把Delphi代码中注释的那句Asio_DisConnedCallback(integer(TAsioClient(FClientLst.Objects[i]))); 去掉注释就可以。
其实只要看看Asio_DisConnedCallback的执行代码就知道,问题依然存在。甚至是Delphi中,将对应的客户端对象释放,对应的socket链接还是没有断开。
后来看C++代码的时候,发现了下面这个函数:
DllExport int Asio_Client_Free(session * isocket)
{
delete isocket;
return ;
}
可以删除socket对象!这实在是太棒了,正是我想要的。
可是,应用中才发现,这个函数带来了另外一个问题。删除自身的socket链接的同时,居然将监控端口的socket也删除了!
无奈,只能另找办法。功夫不负有心人,无意中发现,原来可以用write函数来达到删除socket的目的。
void handle_write(const boost::system::error_code& error,int iuser,int iuser2)
{
if(Callback_writedata!=NULL)
{
// std::cout << "write ok " << iuser << "\n" ;
Callback_writedata(iuser,iuser2);
}
if (!error)
{ }
else
{
socket_.close();
if(Callback_DisConn!=NULL)
{
Callback_DisConn(userdata);
} delete this;
}
}
从上面的代码可以看到,如果write出错,函数会disconn的回调函数,并且"delete this"。终于可以解决问题了啊。
try
if TAsioClient(FClientLst.Objects[i]).Socketptr > then begin
TAsioClient(FClientLst.Objects[i]).Write(@bytes[],);
except
end;
只要在一段时间没数据收发以后,随便给这个客户端发点东西,如果发送错误,自动会断开链接。
mmz-asio4delphi死链接的解决办法的更多相关文章
- discuz x3在DIY模块中调用伪静态不成功,显示动态链接的解决办法
discuz x3在DIY模块中调用伪静态不成功,显示动态链接,然而其他的链接正常显示伪静态. 后台启用伪静态后,发现论坛版块.帖子点击链接,伪静态正常显示,然后在门户首页DIY显示的帖子,点进去后发 ...
- CuteFTP文件列表按名称排序,有中文文件名时,软件死掉的解决办法
看到很多人的解决办法是切换到一个没有中文的文件夹,点击排序后,再切换回来,这个的确是可以解决问题,但是有些繁琐! 直接一步到位的解决办法是: 依次点击菜单:工具->全局选项->导航-> ...
- root用户ssh可以登录,xftp通过sftp不能登录链接CentOS解决办法
xftp显示无法连接到xx.xx.xx(服务器地址) 解决办法: 把/etc/ssh/sshd_config文件中的Subsystem sftp /usr/libexec/openssh/sftp-s ...
- 微信内无法自动跳转外部浏览器打开H5分享链接的解决办法
很多情况下我们用微信分享转发H5链接的时候,都无法在微信内打开,即使开始能打开,过一段时间就会被拦截,拦截后再打开微信会提示 “已停止访问该网址” ,那么导致这个情况的因素有哪些呢,主要有以下四点 1 ...
- (转)ecshop刷新页面出现power by ecshop和链接的解决办法
当小伙伴在使用echop模板进行修改的时候,如果你删掉底部自带版权后,再调试程序刷新界面的时候,时不时就会冒出一个power by ecshop,而且是带有链接的,很不舒服,所以需要去掉,下面是最简单 ...
- ecshop刷新页面出现power by ecshop和链接的解决办法
当小伙伴在使用echop模板进行修改的时候,如果你删掉底部自带版权后,再调试程序刷新界面的时候,时不时就会冒出一个power by ecshop,而且是带有链接的,很不舒服,所以需要去掉,下面是最简单 ...
- delphi假死线程堵塞解决办法
Delphi的高效不多说... 俗话说:真正的程序员用C语言,聪明的程序员用Delphi,一点都不假,和C++比它比C++更简单,更容易上手,功能丝毫不逊色C++,比起VB,毫无疑问比VB好多了,重要 ...
- DedeCMS使用channelartlist循环,不能获取外部链接的解决办法
Dede在制作下拉菜单时,可以使用channelartlist循环调用顶级栏目和子栏目,但该标签不能获取外部链接, 下拉菜单时一段代码搞定多个顶级栏目和子级栏目的同时输出. <div> ...
- 腾讯云服务器ssh登录老是自动断开链接的解决办法
vim /etc/ssh/sshd_config 找到下面两行 #ClientAliveInterval 0 #ClientAliveCountMax 3 去掉注释,改成 ClientAliveInt ...
随机推荐
- [Swift]LeetCode926. 将字符串翻转到单调递增 | Flip String to Monotone Increasing
A string of '0's and '1's is monotone increasing if it consists of some number of '0's (possibly 0), ...
- dedecms搜索模板,使用{dede:list}标签调用自定义字段不显示(空白)
前几天使用织梦做一个搜索功能,正常使用{dede:list}调用自定义内容模型中的自定义字段,代码如下:(自定义字段的调用可以参考:http://www.dede58.com/a/dedejq/523 ...
- 一个JavaWeb搭建的开源Blog系统,整合SSM框架
搬砖有暇,捣鼓了一个简单的Blog系统(项目地址https://github.com/lenve/JavaEETest/tree/master/MyBlog),适合以下人群学习: 1.已经掌握了jsp ...
- 重写equals的详细说明
返回目录 原文地址Java equals() 方法总结 equals() 超类 Object 中有这个 equals() 方法,该方法主要用于比较两个对象是否相等.该方法的源码如下: public b ...
- Chapter 4 Invitations——27
"Myself, obviously." He enunciated every syllable, as if he were talking to someone mental ...
- AJAX应用【股票案例、验证码校验】
一.股票案例 我们要做的是股票的案例,它能够无刷新地更新股票的数据.当鼠标移动到具体的股票中,它会显示具体的信息. 我们首先来看一下要做出来的效果: 1.1服务器端分析 首先,从效果图我们可以看见很多 ...
- Vim编辑器显示行数
很多时候,我们编写代码的时候,编译器报错,在某一行,这时我们虽然可以:行数来跳转,但是没有直观的行数,总是感觉不妥,vi和vim默认是没有行号的,那么怎么办呢?下面我就教你怎么设置行号. 工具: 一台 ...
- leetcode — best-time-to-buy-and-sell-stock
/** * Source : https://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock/ * * * Say you have ...
- leetcode — merge-sorted-array
import java.util.Arrays; /** * Source : https://oj.leetcode.com/problems/merge-sorted-array/ * * * G ...
- Docker镜像构建的两种方式(六)--技术流ken
镜像构建介绍 在什么情况下我们需要自己构建镜像那? (1)当我们找不到现有的镜像,比如自己开发的应用程序 (2)需要在镜像中加入特定的功能 docker构建镜像有两种方式:docker commit命 ...