免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 8218 | 回复: 24
打印 上一主题 下一主题

非阻塞socket,如何检测出断连、无效socket两个异常? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-06-03 09:58 |只看该作者 |倒序浏览
  1. my $select = new IO::Select($$hd_socket);
  2. my ($read_set, $write_set, $error_set) = IO::Select->select($select, $select, $select, $TIMEOUT);
复制代码
这种socket句柄,有两种情况如何检测到:
1、建立连接的Server IP可达,但是要连接的端口没有监听,这种情况下socket是没有建立成功,但是$read_set, $write_set 返回都是0。

2、socket已经建立,在server或者client断开连接,如何检查,$read_set, $write_set状态为啥也都返回的0 ?

论坛徽章:
0
2 [报告]
发表于 2010-06-03 10:06 |只看该作者
本帖最后由 黑色阳光_cu 于 2010-06-03 10:11 编辑

1 端口没打开能连接上?
2 检测send和recv的返回值。比如对端正常关闭时,返回EOF。select当然返回可读,你不去recv,咋知道收到什么数据呢?

论坛徽章:
0
3 [报告]
发表于 2010-06-03 10:20 |只看该作者
我也很奇怪,但是测试情况是这样的。
10.12.105.50 可达,但是不没有监听端口41228,
然后建立连接的时候,返回码如下。
print "state is [ $#$read_set . $#$write_set . $#$error_set]\n";
...... HOST[2] ......
state is [ -1 . 0 . -1]

论坛徽章:
0
4 [报告]
发表于 2010-06-03 10:23 |只看该作者
send一下,然后读$!,看看有什么报错不

论坛徽章:
0
5 [报告]
发表于 2010-06-03 10:35 |只看该作者
如果send就异常退出了。。。

论坛徽章:
0
6 [报告]
发表于 2010-06-03 10:39 |只看该作者
如果send就异常退出了。。。
suposonic 发表于 2010-06-03 10:35



管道破裂了.在程序的开头加一句:
$SIG{PIPE} = "ignore";

论坛徽章:
0
7 [报告]
发表于 2010-06-03 10:56 |只看该作者
select只是保证,接下来的读写不会被阻塞,具体读写的结果,要靠检测send recv的返回值。

论坛徽章:
0
8 [报告]
发表于 2010-06-03 10:58 |只看该作者
为啥不能像c代码一样,呵呵有点麻烦,

这样就必须调用recv、send来检查这样的此类异常socket?

论坛徽章:
0
9 [报告]
发表于 2010-06-03 11:00 |只看该作者
本帖最后由 黑色阳光_cu 于 2010-06-03 11:01 编辑
为啥不能像c代码一样,呵呵有点麻烦,

这样就必须调用recv、send来检查这样的此类异常socket?
suposonic 发表于 2010-06-03 10:58



http://fanqiang.chinaunix.net/pr ... 01-09-13/2227.shtml

“讨论关于利用select()检测对方 Socket关闭的问题:

仍然是本地Socket有东东可读,因为对方Socket关闭时,会发一个关闭连接
通知报文,会马上被select()检测到的。关于TCP的连接(三次握手)和关
闭(二次握手)机制,敬请参考有关TCP/IP的书籍。

不知是什么原因,UNIX好象没有提供通知进程关于Socket或Pipe对方关闭的
信号,也可能是cpu所知有限。总之,当对方关闭,一执行recv()或read(),
马上回返回-1,此时全局变量errno的值是115,相应的sys_errlist[errno]
为"Connect refused"(请参考/usr/include/sys/errno.h)。所以,在上
篇的for(;;)...select()程序块中,当有东西可读时,一定要检查recv()或
read()的返回值,返回-1时要作出关断本地Socket的处理,否则select()会
一直认为有东西读,其结果曾几令cpu伤心欲断针脚。不信你可以试试:不检
查recv()返回结果,且将收到的东东(实际没收到)写至标准输出...
在有名管道的编程中也有类似问题出现。具体处理详见拙作:发布一个有用
的Socket客户方原码。  ”

“至于主动写Socket时对方突然关闭的处理则可以简单地捕捉信号SIGPIPE并作
出相应关断本地Socket等等的处理。SIGPIPE的解释是:写入无读者方的管道。
在此不作赘述,请详man signal。  ”

论坛徽章:
0
10 [报告]
发表于 2010-06-03 11:05 |只看该作者
1.端口不存在

      很幸运,对于端口不存在,对方(linux)在IP层会直接发一个RST(Reset)响应直接终止掉连接,客户端直接把连接终止。在Windows环境下不太一样, 如果对方为Windows服务器,则不会回RST响应,这种情况下与主机不存在一致。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP