【Linux网络编程】IO模型与服务器模型

来源:互联网 发布:ubuntu文件服务器搭建 编辑:程序博客网 时间:2024/04/19 09:56

IO模型

阻塞IO

一般系统默认的IO为阻塞IO,等待IO时进程或线程睡眠。

非阻塞IO

就在执行到IO操作时,没有从缓冲区读到数据,就会从IO操作下面继续执行
注意:对于这种操作一般采用轮询(循环)的方式

fcntl 处理描述符相关联的操作方式

int fcntl(int fd, int cmd, ... /* arg */ );          功能:  文件描述符的控制操作函数,具体操作有命令来决定          参数:                fd    要操作哪一个已经存在的描述符                cmd   文件描述符的控制操作命令                       F_GETFL    获取文件描述符的状态标志,可以不用第三个参数                       F_SETFL    设置文件描述符的状态标志,必须设置第三个参数                arg    命令对应的具体操作是什么,具体找到手册,查看命令对应的选项          返回值:                     F_DUPFD  The new descriptor.                     F_GETFD  Value of file descriptor flags.                     F_GETFL  Value of file status flags.//返回文件的状态标志                     F_GETLEASE                              Type of lease held on file descriptor.                     F_GETOWN Value of descriptor owner.                     F_GETSIG Value of signal sent when read or write becomes possible, or zero for traditional SIGIO behavior.                     F_GETPIPE_SZ                              The pipe capacity.                     All other commands                              Zero.   成功   0                     On error, -1 is returned    //失败   -1          【注意】            在使用fcntl时,注意他的操作方式分为三步:            读   -- >   改    -- >  写            flag = fcntl(fd, F_GETFL)           -->  读            flag  = flag | O_NONBLOCK;  -->  改            fcntl(fd, F_SETFL, flag)               -->  写

多路复用IO

事先在程序中,设定用户要实现的IO操作,然后在实现的IO操作之间,对
相应的描述符进行检查,看哪一个描述符符合条件,执行符合条件的描述符的IO操作。

#include <sys/time.h>#include <sys/types.h>#include <unistd.h>int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);        功能:  使用select检测多路文件描述符,条件满足立刻返回,否则阻塞        参数:                      nfds   获取的有效的最大描述符  加  1                      readfds   读描述符集合(里面存放的是可以读入数据的描述符)                                      fd_set里面是一个数组,用来存放描述符                      writefds  写描述符集合                      exceptfds 异常描述符集合                      timeout   延时                               struct timespec {                                   long    tv_sec;         /* seconds      设置秒数 */                                   long    tv_nsec;        /* nanoseconds  设置微妙数 */                               };注意:两者必须同时设置,才能生效        返回值:            成功  返回有效描述符的个数            失败  -1        【注意】              在使用select函数之前需要添加描述符到对应的集合中,select函数会对描述符进行检测,看哪些描述符有效,然后把有效的描述符留在集合中(readfds) ,把无效描述符从集合中剔除掉。         void FD_CLR(int fd, fd_set *set)         功能:  从set指向的描述符集合中清除一个描述符fd         void FD_ZERO(fd_set *set);         功能:  从set指向的描述符集合中清除所有描述符         void FD_SET(int fd, fd_set *set);         功能:往描述符集合中添加描述符         参数:                 fd   就是要添加的描述符                set  代表的就是描述符集合         注意:事先把描述符添加到集合中         int  FD_ISSET(int fd, fd_set *set);         功能: 用来测试描述符fd是否是set所指向描述集合中有效元素         注意:应该在select函数之后使用,判断描述符         1、定义一个描述符集合fd_set类型的变量readfds         2、通过select函数检测描述符集合中的描述符,是否条件满足         3、要向执行某一路具体的IO操作,首先需要进行描述符的判断FD_ISSET

服务器模型

服务器模型

通过循环查询哪些客户端需要提供服务,浪费CPU资源,在TCP协议中,循环操作尽量不采用这种方式。

并发服务器

可以通过创建父子进程或者创建线程的方式。

父子进程:
用父进程来实现客户端的连接处理,子进程用来跟客户端通信(传输数据)。

线程的方式:
因为要用到acceptfd实现服务器和客户端的通信,所以在accept之后,创建线程,然后把acceptfd这个变量通过值传递的方式传递给线程函数来进行处理操作(数据通信发送数据和接收数据),线程的回收参考这篇文章Linux C中回收线程资源的方法

0 0
原创粉丝点击