缺省状态下,套接口时阻塞方式的。这意味着当一个套接口调用不能立即完成时,进程进入睡眠状态,等待操作完成。我们将可能阻塞的套接口调用分成四种。
1.输入操作:read、readv、recv、recvfrom和recvmsg函数。TCP时一个字节流,数据到来前一直会睡眠,UDP如果接收缓冲区为空,进程将在一个UDP数据报到来之前睡眠。
在一个非阻塞套接口上,如果输入操作不能被满足,他们将会立即返回一个EWOULDBLOCK错误。
2.输出操作:write、writev、send、sendto和sendmsg函数。对TCP socket内核从应用进程缓冲区向套接口发送缓冲区中拷贝数据。如果在套接口发送缓冲区中没有空间,进程会一直睡眠到腾出空间。
3.接收外来连接:accept函数。如果在一个i额阻塞套接口上调用accept函数,而且没有新的连接,进程就会进入睡眠状态。如果在一个非阻塞套接口上调用accept函数,而且没有新的连接,将返回EWOULDBLOCK错误。
4.初始化外出的连接:用于TCP的connect函数。用于TCP的connect函数,展示了TCP连接的建立包含一个三路握手过程,而且conect函数在客户接收到它的SYN的ACK前不会返回。这意味着TCP connect总是会使调用它的进程阻塞起码到服务器的一次往返时间
一、非阻塞connect
当在一个非阻塞TCP的套接字上调用connect时,connect将立即返回一个EINPROGRESS错误。
非阻塞的connect有三个用途:
1.我们可以把三路握手叠加在其他处理上。
2.我们可以使用这个技术同时建立多个连接。
3.既然使用select等待连接的建立,我们可以给select指定一个时间限制,使得我们能够缩短connect的超时。
非阻塞connect有一些必须处理的细节:
1.尽管套接字是非阻塞的,如果连接到的服务器在同一个主机上,那么当我们调用connect时,连接通常立刻建立。我们必须处理这种情形。
2.有关于select和非阻塞connect的以下两个规则:(1)当连接成功建立时,描述符变为可写
(2)当连接建立遇到错误时,描述符变为既可读又可写。
二、非阻塞accept