您的位置:首页 > 理论基础 > 计算机网络

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

2017-04-10 19:08 615 查看

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中回收线程资源的方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息