Linux Socket - 内核非阻塞功能

Posted Benedict97

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux Socket - 内核非阻塞功能相关的知识,希望对你有一定的参考价值。

select 函数

int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval*timeout); 

fd_set * readfds

需要监视变化的文件描述符
    只要有一个文件可读就返回>0
    没有文件可读
        超出timeout时间,返回=0
    发生错误返回负值
传入NULL表示不关心任何文件 

fd_set * readfds

需要监视变化的文件描述符
    只要有一个文件可写就返回>0
    没有文件可读
        超出timeout时间,返回=0
    发生错误返回负值
传入NULL表示不关心任何文件

fd_set * errorfds

同上:监视异常文件

struct timeval* timeout

select的超时时间
为NULL时:select置于阻塞状态
    直到监视文件发生变化位置
为0s0ms时:select变为纯非阻塞函数
    不管文件描述符是否变化都立刻返回
        有变化返回正数
        无变化返回0
大于0时为等待的超时时间
    select在timeout内阻塞

返回值

有可读文件:表示可读文件的数量 返回值>0
没有可读文件:判断timeout参数超时
    超出timeout时间后 返回值=0
    

FD_ZERO

清空文件描述符集

FD_SET

在文件描述符集合中增加一个新的

FD_CLR

删除一个文件描述符

FD_ISSET

测试指定的文件描述符是否在集合中

SOCKET函数

int socket(int domain, int type, int protocol);
int sockfd=socket(AP_INET, SOCK_STREAM | SOCK_NOBLOCK, IPPROTO_TCP);

ACCEPT函数

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
    flags:  SOCK_NOBLOCK
            SOCK_CLOEXEC

FCNTL函数

fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK);

IOCTL函数

ioctl(sockfd, FIONBIO, 1);//1:非阻塞 0:阻塞

accept,connect,recv(recvfrom),send(sendto),closesocket,select(poll或epoll)

1)accept在阻塞模式下,没有新连接时,线程会进入睡眠状态;非阻塞模式下,没有新连接时,立即返回WOULDBLOCK错误。

2)connect在阻塞模式下,仅TCP连接建立成功或出错时才返回,分几种具体的情况,这里不再叙述;非阻塞模式下,该函数会立即返回INPROCESS错误(需用select检测该连接是否建立成功)

3)recv/recvfrom/send/sendto很好理解,因为这两类函数读写socket文件描述符的接收/发送缓冲区。

4) select/poll/epoll并不是真正意义上的阻塞,它们的阻塞是由于它们最后一个timeout参数决定的,timeout大于0时,它们会一直等待直到超时才退出(相等于阻塞了吧,^_^),而timeout=-1即永远等待。

5)closesocket也不是真正意义上的阻塞,它其实是指是否等待关闭。它受套接字选项SO_LINGER和SO_DONTLINGER的影响。

若SO_DONTLINGER或SO_LINGER的间隔=0时,closesocket就是非等待关闭的,但是当SO_LINGER的间隔>0时,closesoket就是等待关闭的,直到剩余数据都发送完毕或直到超时才退出。

(但是这个地方只有对于阻塞的套接口才有用,如果是非阻塞的套接口,它会立即返回并且指示错误WOULDBLOCK)。

以上是关于Linux Socket - 内核非阻塞功能的主要内容,如果未能解决你的问题,请参考以下文章

从linux源码看socket的阻塞和非阻塞

从linux源码看socket的阻塞和非阻塞

从 linux 源码看 socket 的阻塞和非阻塞

Linux Socket

linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)

linux socket write()函数阻塞卡住线程问题(线程无法结束)write()非阻塞代码