原生SOCKET通讯异常--高手指点

gxj760998 2012-01-17 03:49:14
使用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发送又是正常的?


此问题困恼多日,无法找到原因,还请高手指点一二,谢谢!
...全文
165 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
gxj760998 2012-02-04
  • 打赏
  • 举报
回复
过年回家,迟了结贴!
另外还是没有找到满意的答案,多谢楼上三位的支持。
zhuang_bx 2012-01-20
  • 打赏
  • 举报
回复
arg:=1;
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); //设置为阻塞模式
gxj760998 2012-01-18
  • 打赏
  • 举报
回复
自己还是不明白原因所在。
不明白为何建立好通讯后,都在正常发送数据,但这个SELECT检测有问题。
且内网正常、外网不正常。。
bdmh 2012-01-18
  • 打赏
  • 举报
回复
阻塞式,超时了呗,用非阻塞是,线程处理

网上有socket的6中模式,可以看看
haitao 2012-01-17
  • 打赏
  • 举报
回复
Select的时间单位好像是百万分之一秒?
会不会因此在延时大一点的公网就被卡了?

1,593

社区成员

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

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