前言:
当我们要编写一个echo服务器程序的时候,需要对用户从标准输入键入的交互命令做出响应。在这种情况下,服务器必须响应两个相互独立的I/O事件:1)网络客户端发起网络连接请求,2)用户在键盘上键入命令行。我们先等待哪个事件呢?没有哪个选择是理想的。如果在acceptor中等待一个连接请求,我们就不能响应输入的命令。类似地,如果在read中等待一个输入命令,我们就不能响应任何连接请求。针对这种困境的一个解决办法就是I/O多路复用技术。基本思路就是使用select函数,要求内核挂起进程,只有在一个或多个I/O事件发生后,才将控制返回给应用程序。--《UNIX网络编程》
概述:
I/O多路复用,I/O就是指的我们网络I/O,多路指多个TCP连接(或多个channel),复用指复用一个或少量线程。
I/O多路复用模型(multiplexing model):
06fig03.gif
I/O多路复用介绍
关键技术点:
1,怎么区分应用进程和内核。
根据下图中的OSI七层模型和网际网协议族相比,分割线就是用户进程和内核是以传输层为分割线,会话层(包含)以上为用户进程,下四层为内核。
例子:上三层,web客户端比如浏览器、web服务器这些都属于应用层,里面跑的程序则是应用进程。下四层处理所有的通信细节,发送数据,等待确认,给无序到达的数据排序等等。
用户进程和内核.png
2,有两次系统调用分别是select和recvfrom。
- 2.1 select
select是I/O多路复用的精髓,对应的操作系统中调用的系统的select函数,该函数会等待多个I/O事件(比如读就绪,写)的任何一个发生,并且只要有一个网络事件发生,select线程就会执行。如果任何一个事件发生则阻塞。函数如下
#include<sys/select.h>
#include<sys/time.h>
int select(int maxfdpl,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval *timeout);
- 2.2 recvfrom
recvfrom一般用于UDP协议中,但是如果在TCP中connect函数调用后也可以用。用于从(已连接)套接口上接收数据,并捕获数据发送源的地址。也就是我们本文中以及书中说的真正的I/O操作。