Notes on UNPv1 ch.6

http://www.cnblogs.com/cenhao/archive/2011/09/08.html


  1. Unix下有5I/O模型阻塞型I/O, 非阻塞型I/O, I/O多路复用信号驱动I/O, 异步I/O. (Page.154)

  2. 阻塞型I/O是最普遍的I/O模型并且是socket的默认模式此模式下I/O会阻塞至数据准备完毕并切拷贝到进程内存才会返回. (Page.154)

  3. 非阻塞型I/O就是在一次I/O操作时如果进程不休眠等待就无法完成本次操作(即当前没有数据准备好), 那么就返回一个错误(EWOULDBLOCK)而不是一直阻塞. (Page.155)

  4. I/O多路复用也会阻塞但是与阻塞型I/O不同, I/O多路复用是阻塞在一个多路复用函数(select, poll)而不是阻塞在直接的读写操作(read, write), 并且I/O多路复用的阻塞可以同事等待多个描述符与之相似的有多线程/多进程+阻塞型I/O(Page.157)

  5. 信号驱动I/O就是在内核准备好数据之后想进程发送一个SIGIO信号告知可以进行I/O操作了. (Page.157)

  6. 异步I/O与信号驱动I/O相似不同点在于异步I/O会在数据准备好之后自动把数据拷贝进进程指定的内存空间之后才通知进程I/O操作完成. (Page.158)

  7. 注意在从内核中拷贝数据到用户进程内存也是阻塞的一种所以只有异步I/O才是真正的非阻塞异步而其余四种I/O模型都算是阻塞型的. (Page.160)

  8. I/O多路复用的本质就是告知内核我们对某些指定的描述符的指定状态感兴趣如果在指定的时间内出现了该状态那么返回告知否则超时后返回告知没有出现指定状态. (Page.161)

  9. 可以设置I/O多路复用的等待时间可以永远等待(select: NULL; poll: INFTIM), 不等待马上返回(select, poll设置0), 等待指定时间(指定相应字段). (Page.161).

  10. Select在阻塞时会被信号中断并且在不同的平台不能保证select会被重启所以应做好接受select返回的EINTR错误并重启的准备(poll也是应该这么做). (Page.162)

  11. selectpoll等待时间的精度会受到内核时钟分辨率以及内核调度的影响. (Page.162)

  12. select所等待的描述符只会在两种情况下返回异常状态其中与网络编程相关的是收到了带外数据文件符返回错误并不是异常状态. (Page.162)

  13. select使用的fdset可以直接用等号赋值. (Page.163)

  14. 如果对某种状态不感兴趣可以直接吧对应状态的fdset指针设为NULL. (Page.163)

  15. 可以通过FD_SETSIZE常量获得fdset的最大容量(通常为1024). (Page.163)

  16. select的返回值是三种状态的fdset中仍然打开的位的个数所以如果对一个描述符的多个状态感兴趣那么如果这个描述符同时可读可写那么应该算作两个位. (Page164).

  17. 在以下四种情况一个描述符为可读: (1)内核中的数据量大于SO_RCVLOWAT选项指定的值(TCPUDP的默认值都为1个字节); (2)链接的读链接被关闭(收到了FIN); (3)监听socket的监听队列中有已经完成3次握手的链接; (4)描述符有错误发生. (Page.164)

  18. 在以下四种情况一个描述符为可写: (1)内核的发送缓存的空间不小于SO_SNDLOWAT指定的值(TCPUDP通常为2048); (2)写链接被关闭; (3)socket通过非阻塞connect完成了TCP三次握手或者失败; (4)描述符有错误发生. (Page.164)

  19. 一般来说, select返回监听socket可读时对这个socket的描述符进行accept操作是不会出现阻塞的但是在某些情况下仍然可能阻塞所以这里要小心处理应把监听socket设为非阻塞. (Page.164)

  20. Select返回一个socket可写时虽然内核的发送缓存空间不小于SO_SNDLOWAT指定的值但是如果需要发送的数据量超过了缓存空间仍然可能出现阻塞所以应把socket设为非阻塞才能真正避免阻塞. (Page.164)

  21. 如果对一个没有”reader”的描述符进行写操作那么就会产生SIGPIPE, 写操作返回错误错误码为EPIPE. 因此对关闭了写链接的socket或则收到RSTsocket进行写操作都会出现这种现象. (Page.164)

  22. 当一个socket出现错误时那么就会被标记为即可读也可写但是这不是异常状态. (Page.164)

  23. UDP是无连接的它并没有实际的内核发送缓存所以只要SO_SNDLOWAT所设定的值比SO_SNDBUF所设定的值小即可. (Page164)

  24. 目前大部分系统提供”无限”的文件描述符描述符的数量由系统的内存和管理员设定的限制决定. (Page.165)

  25. 如果想要增大FD_SET所能容纳的文件描述符的数量最为可靠和根本的方法是修改FD_SETSIZE的值并重新编译内核. (Page.165)

  26. selectI/O多路复用函数是不适宜和一些有自己实现内部缓存的函数共用的例如selectstdio共用通过fgets读取文件如果stdio一次把多行放入自己的缓存,fgets一次就只读取一行导致重复多次调用select以获取可读的描述符stdio对应的描述符其实是一直可读的因此后面调用的select都是空转. (Page.171)

  27. shutdownclose的区别: (1)调用shutdown会马上关闭指定链接close会等到描述符的引用计数器为0时才会开始关闭链接; (2)close会同时关闭两个链接,shutdown值关闭指定链接; (3)close后文件描述符不再可用, shutdown后文件描述符是可用的. (Page.172)

  28. 对一个sockeet描述符shutdownSHUT_RD按照UNPv1的说法是如果另一方继续发送数据那么这些数据仍然会被接收方确认只是接收方会自动删掉这些数据,不会交给用户进程而在linux下面如果想这样一个shutdownSHUT_RD的链接发送数据发送方会收到RST. (Page.173)

  29. 对一个socket描述符shutdown SHUT_WR, 那么内核会在发送完缓存中的数据后发送FIN启动断开连接. (Page.173)

  30. SHUT_RDWR相当于先shutdown SHUT_RD, shutdown SHUT_WR. (Page.173)

  31. 应对DoS攻击的简单方法有: (1)使用非阻塞I/O; (2)一个线程/进程单独服务一个客户; (3)使用超时机制. (Page.180)

  32. pselect的精度更高(纳秒), 而且可以设置信号掩码. (Page.181)

  33. select不同, poll的某些状态不需要自行设定(也无法自行设定)就会在出现这种状态的时候返回: POLLERR, POLLHUPPOLLNVAL. (Page.183)

  34. POLL不同状态对应的选项比较混乱可能一种状态对应两种可能的选项需要查看书本. (Page.184)


你可能感兴趣的:(Notes on UNPv1 ch.6)