使用delphi7+原生socket函数写了一个TCPIP通讯服务器,实现了一个通过 原生select()来检测当前连接是否有效的功能,
在内部测试时,没有问题,能有效检测各种设备的断线与重练,效果较好。但部署到应用时,出现了问题,select老返回超时.但使用recv的接收与发送则正常!现在请高手指点一二,看看问题在哪里。
代码:
LTime.tv_sec := ATimeout div 1000;
LTime.tv_usec := (ATimeout mod 1000) * 1000;
Result := Select(0, AReadSet, AWriteSet, AExceptSet, @LTime);
其中:LTime\AReadSet\AWriteSet 每次检查都重新设置了。
通讯模式:阻塞通讯。
内部网络环境说明:
内部公示网络、使用192.168的网段,设备6-10台,select可读检测正常(判断当前连接是否有效)、设备数据的发送与接收也正常。外部网络环境:
服务器端:程序部署在服务器上,使用192.168的内网IP与端口, 有固定外网IP端口 转发数据到 服务器上。
设备部署:通过ADSL网络自动拨号后,设备跨外网发送数据到 外网IP与端口。现象:数据通讯发送与接收正常,但 select可读检查每次都返回0,设备数量超过20台。设备通讯:单台设备通讯间隔不超过3秒,有应用心跳包存在。疑问:
为何select可读检测在外网实际应用时,总返回为0,但此时使用recv的接收与send发送又是正常的?
此问题困恼多日,无法找到原因,还请高手指点一二,谢谢!
在内部测试时,没有问题,能有效检测各种设备的断线与重练,效果较好。但部署到应用时,出现了问题,select老返回超时.但使用recv的接收与发送则正常!现在请高手指点一二,看看问题在哪里。
代码:
LTime.tv_sec := ATimeout div 1000;
LTime.tv_usec := (ATimeout mod 1000) * 1000;
Result := Select(0, AReadSet, AWriteSet, AExceptSet, @LTime);
其中:LTime\AReadSet\AWriteSet 每次检查都重新设置了。
通讯模式:阻塞通讯。
内部网络环境说明:
内部公示网络、使用192.168的网段,设备6-10台,select可读检测正常(判断当前连接是否有效)、设备数据的发送与接收也正常。外部网络环境:
服务器端:程序部署在服务器上,使用192.168的内网IP与端口, 有固定外网IP端口 转发数据到 服务器上。
设备部署:通过ADSL网络自动拨号后,设备跨外网发送数据到 外网IP与端口。现象:数据通讯发送与接收正常,但 select可读检查每次都返回0,设备数量超过20台。设备通讯:单台设备通讯间隔不超过3秒,有应用心跳包存在。疑问:
为何select可读检测在外网实际应用时,总返回为0,但此时使用recv的接收与send发送又是正常的?
此问题困恼多日,无法找到原因,还请高手指点一二,谢谢!
解决方案 »
- 关于TThread的释放问题,求高人。
- delphi里面有没有既可以删除文件又可以删文件夹的通用函数?
- 在DELPHI7下有TClientSocket、TServerSocket吗?
- DBGrid的格線能不能画成双線或格線加粗?(UP有分)
- 请教!!!在QuickRep中如何检测打印机的状态(如缺纸)?
- 如何用delphi控制ole容器里的word????
- 急:连接服务端,如果服务端没有开,怎么让程序不弹出系统错误,弹出自己的错误?
- 如何把文本文件作成资源文件?
- shelllistview拖放问题
- delphi中如何实现停止oracle查询?
- Delphi7,调用RES中装入的BMP图片
- 一个数据录入的窗口,不同用户使用的字段不同,如何灵活安排布局呢?
会不会因此在延时大一点的公网就被卡了?
不明白为何建立好通讯后,都在正常发送数据,但这个SELECT检测有问题。
且内网正常、外网不正常。。
ioctlsocket(FSocket, integer(FIONBIO), arg); //设置为非阻塞模式connect(FSocket, @psa, sizeof(psa)));
timev.tv_sec := 5; //超时5秒
timev.tv_usec := 0;
arg := select(0, @fd_read, @fd_read, nil, @timev);
if (arg = 0) or (arg= SOCKET_ERROR) then Exit ; //连接失败
arg:=0;
ioctlsocket(FSocket, integer(FIONBIO), arg); //设置为阻塞模式