------------恢复内容开始------------
------------恢复内容开始------------
服务器发送的FIN会转换为SOCKET的EOF,但是如果客户端阻塞于读stdin,那么会很久以后才能收到这个EOF,即它不能第一时间知道服务器已经要关闭了.
I/O复用的应用场景
- 用户处理多个描述符时,必须使用IO复用
- 一个用户同时处理多个套接字
- 服务器既要处理监听套接字,又要处理已连接套接字
- 既要使用TCP,又要使用UDP
- 服务器要处理多个服务
同步IO和异步IO的概念
同步IO使得调用进程阻塞,直到IO操作完成.
异步IO不会使调用进程阻塞,调用进程立即返回.
(只有POSIX异步IO模型是真正的异步IO,IO操作不会导致程序阻塞[IO和程序执行同时进行])
select函数
略
套接字描述符就绪条件
套接字满足下面条件之一即准备好读:
- 接收缓冲区数据字节数大于低水位标记。对TCP和UDP来说,值为1
- 收到了对端的FIN,此时调用read会立即返回EOF
- 对于监听套接字来说,已完成连接数不为0
- 套接字有错误待处理,此时输入输出不会阻塞,会立即返回-1
套接字满足下面条件之一即准备好写:(写是相当容易满足的)
- 套接字的发送缓冲区可用空间大于套接字设置的低水位值(TCP和UDP都是2048),并且该套接字已连接(或者像UDP一样不需要连接)
- 写半部关闭,此时写会引发SIGPIPE
- 使用非阻塞式的connect已经创建连接,或者connect以失败告终
- 有套接字错误待处理,此时写将会返回-1
注意:如果套接字发生了错误,那么select会认为它此时可读可写。
UDP应该总是可写的(缓冲区仅用于一次交互,只要发送低水位值小于等于发送缓冲区大小)
shutdown
- close是引用计数的,但是shutdown立即触发四次挥手。
- close既关闭读又关闭写,但是有时候我们仅仅不再写(这称为半关闭),这使用shut_wr选项即可
为什么同时使用select和带缓冲的读函数是有罪的?
如果你用带缓冲的读函数,你很可能只读了一行,输入缓冲区里还有数据。但是select并不知道这部分缓冲区的存在,select看的是套接字的缓冲区,它发现里面没有数据就不会触发。
------------恢复内容结束------------