免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: suposonic
打印 上一主题 下一主题

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

论坛徽章:
0
21 [报告]
发表于 2010-06-03 14:15 |只看该作者
恩,看来也只能这样了,谢谢你的帮忙,lol

论坛徽章:
0
22 [报告]
发表于 2010-06-03 14:16 |只看该作者
回复  黑色阳光_cu


    请教一下,$#$read_set是什么啊?

$#不是数组的最后一个元素的索引么?
maxpayne 发表于 2010-06-03 13:58



    是的,select返回的也是数组

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

还有getsockopt($sock, SOL_SOCKET, SO_ERROR)的办法,不通用~

linux上可以用:
在select返回成功后
my $packed = getsockopt($sock, SOL_SOCKET, SO_ERROR);
my $errno = unpack("i", $packed);
if ($errno > 0)
{
    # error
}


这时$errno 应该为104 "Connection reset by peer"

windows上$errno 为0

论坛徽章:
0
24 [报告]
发表于 2010-06-03 14:58 |只看该作者
那还是使用read、write来检查试试看。

论坛徽章:
0
25 [报告]
发表于 2010-06-03 15:00 |只看该作者
SO_ERROR

当一个socket发生错误的时候,将使用一个名为so_error的变量记录对应的错误代码,这又叫做pending error,so_error为0时表示没有错误发生。一般来说,有2种方式通知进程有socket错误发生:

1、进程阻塞在select中,有错误发生时,select将返回,并将发生错误的socket标记为可读写;

2、如果进程使用信号驱动的 I/O,将会有一个SIGIO产生并发往对应进程;

此时,进程可以通过SO_ERROR取得具体的错误代码。getsockopt返回后,*optval指向的区域将存储错误代码,而so_error被设置为0。

当so_error不为0时,如果进程对socket进行 read操作,若此时接收缓存中没有数据可读,则read返回-1,且errno设置为so_error,so_error置为0,否则将返回缓存中的数据而不是返回错误;如果进行write操作,将返回-1,errno置为so_error,so_error清0
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP