Linux非阻塞connect方法(二)——问题总结

1. 非阻塞socket可调用fcntl或ioctl设置

2.connect的返回值

    非阻塞connect返回-1,并不一定是连接失败,可能是连接过程未完成,此时errno为EINPROGRESS,可通过select检查连接何时完成

3. select的返回值

    1)-1,表示select出错,可以关闭socket,重新发起连接过程

    2)0,表示select超时,此时可能connect还在进行中,可再次进行select,反复数次仍超时,可认为连接失败,需返回失败错误

    3)1,表示存在套接口描述字可读或可写,需根据规则进一步判断是连接成功还是出错

4. 通过socket可读/可写能否判断连接状态

    源自 Berkeley 的实现有两条与 select 和非阻塞 I/O 相关的规则:

        A) 当连接建立成功时,套接口描述符变成 可写(连接建立时,写缓冲区空闲,所以可写)

        B) 当连接建立出错时,套接口描述符变成 既可读又可写(由于有未决的错误,从而可读又可写)

        当发现套接口描述符可读或可写时,可进一步判断是连接成功还是出错。这里必须将B)和另外一种连接正常的情况区分开,就是连接建立好了之后,服务器端发送了数据给客户端,此时select同样会返回非阻塞socket描述符既可读又可写。

    因此,仅从socket可读或可写无法判断socket连接的状态。

5. 如何有效判断连接状态:

    1)getsockopt方法在linux环境下无效

    2)再次执行connect,检查errno值,该方法在Linux环境下有效。测试中发现的问题:

    一次select之后,发现此时套接口描述字可读或可写,再次执行connect,此时errno始终不变,仍未EINPROGRESS,增加select的超时时间结果也一样。

    之后尝试在select返回值为0,或返回值为1,且connect后errno仍为EINPROGRESS(115)时,再次执行select+connect,即再次检测连接状态。此时errno被置为EISCONN(106),connect成功。

    还没有搞清楚原因。

7. socket连接成功后是否重置为阻塞模式

    这要看连接需要什么样的效果。

    如果连接建立成功后,重置socket为阻塞模式。在给服务器发送信息等待接收数据时,如果服务器很忙,而服务器也没设计好,每到来一个客户端就服务,那么后来的要排队,客户端多的话,会导致后来的请求长时间得不到应答,线程一直被阻塞。
    然而,在非阻塞模式下,send和recv也会立即返回。测试发现,非阻塞模式下,recv常常未能接收到数据,返回错误。而在建链之后将socket重置为阻塞,recv的接收正常。

8. socket使用完成后要进行释放

    close(sock_fd)

9. 具有非阻塞属性的接口

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值