Notes on UNPv1 Ch.8

  1. 使用udp的一些比较有名的应用: DNS, NFS, SNMP. (Page.239)
  2. recvfrom和accept函数的相似之处: 最后两个参数用来获取数据的来源; sendto和connect的相似之处: 最后两个参数都用来指定数据的目的地. (Page.241)
  3. recvfrom函数中的数据长度的值理所当然地不包含数据包的头部长度. (Page.241)
  4. 在udp里, 发送和接受长度为0的数据是可以的. 因为udp是无连接的, 所以recvfrom的返回值为0并不代表EOF或者连接的断开. (Page.241)
  5. TCP也可以使用sendto和recvfrom, 但是通常这么做没有任何意义和理由. (Page.241)
  6. UDP的缓存是FIFO的, 并且有大小限制. (Page.243)
  7. 通常来讲, TCP服务器是并行的, 利用多个socket实现多个连接, 每个连接(socket)独享一份数据缓存; 而UDP服务器往往是迭代的, 所以用一个UDP socket服务所有请求, 所以也就只有一份数据缓存. (Page.243)
  8. 如果UDP在调用sendto之前没有绑定ip:port, 那么在第一次调用sendto的时候, 内核会为其根据路由表分配ip:port, 但是ip并不是固定的, 而port分配后就一般情况下就不会再改变. (Page.245)
  9. 由于udp是无连接的, 所以数据的传输是不可靠的, 所以如果直接用recvfrom(或connect后用recv, read)阻塞等待数据可能会导致程序一直阻塞, 所以以阻塞方式等待udp数据最好加上一个超时. (Page.246)
  10. 大部分系统都是弱终端实现: 主机的任意一个接口都可以接收到发往本机的数据包, 即使数据包的目的ip地址和该接口的地址不同; 而任意接口都可以发送本机的数据包, 即使数据包的源ip地址和该接口的ip地址不同 (Page.247, 250)
  11. 对 于某些系统, 如果在使用udp的时候没有绑定ip, 那么在回包的时候, 系统会根据路由表选择合适的ip作为ip数据包的源地址; 而如果绑定了ip地址, 那么回包时则不会查询路由表来确定包的源地址. 注意不是所有系统都会自主选择没有绑定ip地址的udp数据包的ip地址 (Page.248)
  12. 为了避免条目11中的对方回包是自主选择ip, 影响校验数据来源(即受到数据包时检查来包的源地址是否和自己期望的ip地址相同), 校验来包可以使用查询DNS的方法, 或者对方对每一个接口进行单独绑定, 然后使用select之类的函数进行I/O多路复用, 来回避自动选择地址. (Page.248)
  13. udp输出函数的成功返回, 只代表需要发送的数据已经成功地拷贝到接口的数据缓存中, 并不代表数据成功发送或者被对方正确接收. (Page.249)
  14. udp 在没有调用connect指定数据的接收方前, 是无法接收到发生在这次udp通信中发生的异步错误的. 如果一个进程利用同一个udp socket向多个不同的ip发送数据, 其中的某些数据发送失败了, 但是由于udp能够返回异步错误信息只有一个errno, 所以如果在没有connect的时候, 返回异步错误可能是没有意义的. 所以对没有调用connect的udp soceck是无法收到异步错误. (Page.249)
  15. Linux会返回udp的部分"destination unreachable"错误, 即使没有调用connect函数. 只用没有对该socket设定SO_BSDCOMPAT选项, 那么可以收到除了0, 1, 4, 5, 12的"destination unreachable"错误. (Page.249)
  16. 在发送udp数据时, 如果没有绑定ip:port, 那么系统会自动为这个udp socket绑定一个端口, 并且这个端口是不变的; 而ip则会根据路由表而发生变化. (Page.250)
  17. 由于UDP是无连接的, 所以收到的数据报的目的ip地址不一定就是该udp socket绑定的ip地址(如广播数据). 想要了解来包的目的地址, 可以设定IP_RECVDSTADDR选项并使用recvmsg来获得. (Page.251)
  18. 对 一个udp socket调用connect后, 会产生三个变化: (1)数据只能发往connect指定的ip:port, 不需要再使用sendto函数指定发送的目的地, 使用send即可, 如果使用sendto函数会返回EISCONN错误; (2) 只能收到connect指定地址的来包; (3)能够收到异步错误. (Page.252)
  19. UDP可以connect到一个多播/广播地址. (Page.252)
  20. DNS的配置写在/etc/resolv.conf文件中. (Page.254)
  21. 可 以对一个UDP socket多次调用connect, 这样可以实现两种不同的功能: (1)重新设定另一方的ip:port以接受其他数据; (2)可以connect一个类型为AF_UNSPEC的socket, 以实现取消connect的效果, 注意这样做, connect函数可能会返回EAFNOSUPPORT错误, 而且根据平台的不同, upd socket的ip可能会被reset. (Page.254)
  22. 如果知道本次udp通信是点对点的, 使用connect的udp socket的效率会高于未使用connect的udp socket. (Page.255)
  23. bind用来绑定本地的ip:port, 而connect用来指定目的地的ip:port. (Page.255)
  24. TCP 的connect如果指向一个不存在服务的ip:port, 会返回错误; 对udp使用connect不会, 只用在发送数据之后才会知道有错误发生. 但是调用connect的时候, 系统都会为该socket分配ip:port(如果之前没有指定) (Page.256)
  25. udp的接收缓存有限, 如果发送方的发送速度过快, 导致udp接收缓存溢出, 那么数据会被抛弃; 或者发送方发送的数据大小超过接收方的接收缓存, 那么这个数据也会被抛弃(udp面向报文). (Page.261)
  26. 一些系统可以用ping -v命令来查看所有发往本机的icmp报文. (Page.265)

你可能感兴趣的:(Note)