Linux网络编程学习总结

I/O模式

I/O模式提供了一种机制,当一个或多个I/O条件满足时,可以将一个输入操作分为两个不同的阶段,I/O模式分为5中不同的类型,即:阻塞I/O,非阻塞I/O,I/O复用,信号驱动I/O和异步I/O。

select函数

函数:int select(int masfd,fd_set *readset,fd_set *writeset,

fd_set *exceptset,const struct timeval *timeout);

头文件:sys/select.h sys/time.h

说明:该函数允许进程指示内核等待多个时间中的任意个发生,并在一个或多个事件发生或经过指定时间才唤醒进程其中timeeval结构如下:

struct timeval{

    long tv_sec;//秒

    long tv_usec;//微秒

};

timeout函数中起到定时器的作用,其取值含义如下:

取0:相当于非阻塞模式,也就是不用等待,,检查完描述字后立即返回,使用该方法可以有效的轮询集合中的所有文件描述字;

取NULL:将等待,直到有一个描述字准备好后I/O返回;

取设定值:相当于一般的定时器,在描述字准备好I/O或超过了指定时间后才返回。

readset、writeset和exceptset为3个文件描述字集合,select监视集合中定义的描述字,如果不需要监视,可以设定为NULL指针。

关于返回值:

select调用返回时,除了那些已经就绪的描述符外,select将清除readfds、writefds和exceptfds中的所有没有就绪的描述符。select的返回值有如下情况:

1.正常情况下返回就绪的文件描述符个数;

2.经过了timeout时长后仍无设备准备好,返回值为0;

3.如果select被某个信号中断,它将返回-1并设置errno为EINTR。

4.如果出错,返回-1并设置相应的errno。

系统提供了4个宏对描述符集进行操作(sys/select.h和sys/time.h):

void FD_SET(int fd, fd_set *fdset);

void FD_CLR(int fd, fd_set *fdset);

void FD_ISSET(int fd, fd_set *fdset);

void FD_ZERO(fd_set *fdset);

宏FD_SET设置文件描述符集fdset中对应于文件描述符fd的位(设置为1);

宏FD_CLR清除文件描述符集fdset中对应于文件描述符fd的位(设置为0);宏FD_ZERO清除文件描述符集fdset中的所有位(既把所有位都设置为0);

宏FD_ISSET来检测文件描述符集fdset中对应于文件描述符fd的位是否被设置。

poll函数

函数poll提供了和select相似的功能,它可以将套接口设置为非阻塞模式。其和select不同点在于,poll没有使用3个基于位的文件描述符集合,而是采用了pollfd数组。

函数:int poll(struct pollfd *fdarray,nfds_t nfds,int timeout);

头文件:poll.h

说明:成功时返回描述字的个数,如果超时,返回0,如果出错,返回-1。并设置errno的值为如下值之一:

EBADF:一个或多个结构体中指定的文件描述符无效;

EFAULT:fds指针指向的地址超出进程指定的地址空间;

EINTR:请求的事件之前产生一个信号,调用可以重新发起;

EINVAL:nfd参数超出PLIMIT_NOFILE的值;

ENOMEM:可用内存不足,无法完成请求。

其中struct pollfd结构如下:

    struct pollfd{

       int fd;

       short events;

       short revents;

}

其中,event域是监视该文件描述符的掩码,有用户设置,revents域是文件描述符的操作结构掩码,有内核设定。Events域请求的任何事件都可以在revents域中返回,合法事件如下:

POLLIN:有数据可读;

POLLRDNORM:有普通数据可读(不常用);

POLLRDBAND:有优先数据可读;

POLLPRI:有紧迫数据可读;

POLLOUT:学数据不会导致阻塞;

POLLWRNORM:写普通数据不会导致阻塞;

POLLWRBAND:写优先数据不会导致阻塞;

POLLMSG:SIGPOLL消息可用;

此外,revents也可返回如下事件:

POLLER:指定的文件描述符发生错误;

POLLHUP:指定的文件描述符挂起事件;

POLLNVAL:指定的文件描述符非法;

POLLIN=POLLRDNORM|POLLRDBAND

POLLOUT=POLLWRNORM

POLLIN|POLLPRI=select的读

POLLOUT|POLLWRBAND=select的写。

对于函数的timeout参数,情况如下:

大于0:指定等待多长时间;

等于0:立即返回;

为INFTIM:(该值为-1,有些系统定义在poll.h里,有些定义在sys/stropts.h  里,有些没有定义,需要自己定义)表示永远等待。

 

epoll机制

在linux2.6内核以及以上版本上增加了epoll机制,它包含用于处理I/O事件多路分离的一组函数。它在一定程度上弥补了linux内核对异步I/O支持的不足,epoll机制加上非阻塞的I/O可以模拟实习那异步I/O。

epoll机制所使用的数据结构:

typedef union epoll_data{

       void *ptr;

       int fd;

       __uint32_t u32;

       __uint64_t u64;

} epoll_data_t;

struct epoll_event{

       __uint32_t events;

       epoll_data_t data;

}

Epoll_event用于注册所感兴趣的事件和回传所发生待处理的事件,其中epoll_data联合体用来保存触发事件的某个文件描述符的数据。Epoll_event结构中的events字段表示感兴趣事件和触发的事件,其取值为:

    EPOLLIN:表示对于的文件描述符可读;

    EPOLLOUT:表示对应的文件描述符可写;

    EPOLLPRI:表示对应的文件描述符有紧急的数据可读;

    EPOLLERR:表示对于的文件描述符发生错误;

    EPOLLHUP:表示对应的文件描述符被切断;

    EPOLLET:表示对应的文件描述符有事件发生

相关函数

函数(1):epoll_create(int size);

头文件:sys/epoll.h

说明:该函数生成一个epoll专用的文件描述符,其中的参数为指定内核分配size个相关内核对象。

函数(2):epoll_ctl(int epfd,int op,int fd,struct epoll_event *event);

头文件:sys/epoll.h

说明:用于控制某个文件描述符上的时间,可以注册,修改,删除时间,其中epfd为有epoll_create生成的epoll专用文件描述符,op为要进行的操作,取值为:EPOLL_CTL_ADD(注册),EPOLL_CTL_MOD(修改),EPOLL_CTL_DEL(删除);fd为关联的文件描述符,event为指向epoll_event的指针,调用成功返回0,失败返回-1。

函数(3):

epoll_wait(int epfd,struct epoll_event *events,int maxevents,int timeout);

头文件:sys/epoll.h

说明:用于轮询I/O时间的发生。其中,epfd为epoll_create生成的epoll描述符,epoll_event为用于回传代理事件的数组。maxevents为每次能处理的事件数,timeout为等待I/O事件发生的超时值。

Epoll机制的有点

l  支持一个进程打开大数目的socket描述符

l  IO效率不随FD数目增加而线性下降

你可能感兴趣的:(编程,linux,struct,网络,events,linux内核)