socket阻塞模式:执行读写操作后,会一直等待,直到有数据读写操作完成或出错(返回-1);socket非阻塞模式:执行读写操作后,立即返回,返回值不同代表不同含义。两种模式适用不同场景,阻塞方式编码简单,一个线程只能处理一条链路,适用于只有少数链路场景;非阻塞模式一般配合epoll、select使用,一个线程可以同时操作多条链路,服务器软件大都使用这个方式接入。
下面是从其他论坛找到的类似描述,在项目开发过程中,也确实是这样的。
阻塞与非阻塞recv()返回值:
<0:出错或tcp协议栈读缓冲为空;(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)的情况下认为连接是正常的,可以继续接收。
=0:连接关闭,实际时接收到了FIN包;
>0:接收到数据,返回值表示接收到数据长度。
阻塞模式与非阻塞模式下send返回值:
< 0 :出错, (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)表示暂时发送失败,需要重试,其他情况为出错;
> 0 :发送成功,返回发送字节数;
= 0:应该不会发生。
除了send、recv,一般socket操作返回-1,都表示出错,这时需要判断errno值来确认是什么错误,下面三种错误不认为是异常。
EINTR:系统中断,可能其他更高优先级的中断信号;
EWOULDBLOCK:非阻塞模式下才会发回该错误码,表示操作被阻塞了;
EAGAIN:again,我理解是操作系统提示下次再试试。
还有两种常见错误码实际表示断链,下面是在几种机器上测试向不存在端口建链时,对端直接回复RST包拒绝建链,抓包分析、测试分析得出结果如下,socket执行connect时,若对端直接响应REST包,
| Linux | Sun | Hp | Aix |
阻塞 | 104 ECONNREFUSED | 146 ECONNREFUSED | 未测试 | 79 ECONNREFUSED |
非阻塞 | 115 EINPROGRESS | 150 EINPROGRESS | 未测试 | 55 EINPROGRESS |