Qianfeng

DON'T WORRY BE HAPPY
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

unp笔记6:I/O复用:select和poll函数

Posted on 2022-03-14 18:56  RonnieOS  阅读(55)  评论(0编辑  收藏  举报

------------恢复内容开始------------
------------恢复内容开始------------
服务器发送的FIN会转换为SOCKET的EOF,但是如果客户端阻塞于读stdin,那么会很久以后才能收到这个EOF,即它不能第一时间知道服务器已经要关闭了.

I/O复用的应用场景

  1. 用户处理多个描述符时,必须使用IO复用
  2. 一个用户同时处理多个套接字
  3. 服务器既要处理监听套接字,又要处理已连接套接字
  4. 既要使用TCP,又要使用UDP
  5. 服务器要处理多个服务

同步IO和异步IO的概念

同步IO使得调用进程阻塞,直到IO操作完成.
异步IO不会使调用进程阻塞,调用进程立即返回.
(只有POSIX异步IO模型是真正的异步IO,IO操作不会导致程序阻塞[IO和程序执行同时进行])

select函数

套接字描述符就绪条件

套接字满足下面条件之一即准备好

  1. 接收缓冲区数据字节数大于低水位标记。对TCP和UDP来说,值为1
  2. 收到了对端的FIN,此时调用read会立即返回EOF
  3. 对于监听套接字来说,已完成连接数不为0
  4. 套接字有错误待处理,此时输入输出不会阻塞,会立即返回-1

套接字满足下面条件之一即准备好:(写是相当容易满足的)

  1. 套接字的发送缓冲区可用空间大于套接字设置的低水位值(TCP和UDP都是2048),并且该套接字已连接(或者像UDP一样不需要连接)
  2. 写半部关闭,此时写会引发SIGPIPE
  3. 使用非阻塞式的connect已经创建连接,或者connect以失败告终
  4. 有套接字错误待处理,此时写将会返回-1

注意:如果套接字发生了错误,那么select会认为它此时可读可写。
UDP应该总是可写的(缓冲区仅用于一次交互,只要发送低水位值小于等于发送缓冲区大小)

shutdown

  1. close是引用计数的,但是shutdown立即触发四次挥手。
  2. close既关闭读又关闭写,但是有时候我们仅仅不再写(这称为半关闭),这使用shut_wr选项即可

为什么同时使用select和带缓冲的读函数是有罪的?

如果你用带缓冲的读函数,你很可能只读了一行,输入缓冲区里还有数据。但是select并不知道这部分缓冲区的存在,select看的是套接字的缓冲区,它发现里面没有数据就不会触发。

------------恢复内容结束------------