unix网络编程卷1_套接字联网API
UNIX网络编程卷1:套接字联网API
2. 传输层:TCP、UDP、SCTP
TCP状态转换图,全书最重要的图之一

UNIX网络编程第二章

3. 套接字编程简介
以下是UNIX网络编程卷一上的图,查看Linux 这几个地址的定义,有些许差别,Linux的定义如下:
1 |
|

4. 基本TCP套接字编程
内核为每一个监听套接字维护两个队列:



相关知识: 半连接攻击
6. IO复用:select和poll函数
5种IO模型(这部分小林的图解系列图更好)
一个输入操作包括2个不同的阶段:
- 等待数据准备好
- 从内核向进程复制数据

一个非阻塞描述符循环调用recvfrom时,我们称之为轮询。该操作大量消耗CPU时间。

IO多路复用同样是阻塞式的,不过它阻塞在IO复用系统调用上,如select、poll以及epoll,而不是阻塞在真正的IO系统调用上。注意,数据从内核复制到用户空间的那段时间,应用也是阻塞的。

信号驱动式IO模型暂未发现可用场景,就不放图了。
以上所有的IO模型,均为同步IO。
POSIX异步IO框架aio系列已经过时了,在Linux平台,可以使用从Linux内核5.1开始的io_uring异步框架。
注意,IO多路复用是在收到数据时触发读事件,通知上层应用,此时需要将数据复制到用户空间。而异步IO是收到数据,并且将数据从内核复制到了用户空间后,再通知应用处理数据。

五种IO模型的比较:

shutdown函数:
终止网络连接的一般方法是调用close函数,不过close有两个限制,如下:
- close将描述符的引用计数减1,仅在该计数变为0时才关闭套接字。
- close终止读和写两个方向的数据传输。
而shutdown函数,既可以不管引用计数就激发TCP的正常连接终止序列,也可以处理如下这种场景:
我们需要告知对端我们已经完成了数据发送,即使对端仍有数据要发送给我们。
理解为什么一定要四次挥手。

SHUT_RD
:关闭读。套接字接收缓冲区的现有数据将被丢弃。SHUT_WR
:关闭写,TCP称为半关闭。套接字发送缓冲区的现有数据将被发送。SHUT_RDWR
:读写关闭
陈硕的muduo网络库中,即使用了TCP的半关闭功能。
1 |
|
8. 基本UDP套接字编程


11. 名字与地址转换

1 |
|
同时支持IPv4与IPv6的转换函数:
头文件:<netdb.h>


创建一个TCP套接字并连接到一个服务器:


12. IPv4与IPv6的互操作性

拓展: 当数据流路径是 IPv6通道 –> IPv4通道 –>IPv6(通道)时,将采用隧道技术。


总结: IPv6 对 IPv6,IPv4 对 IPv4, IPv4 对 IPv6 采用映射。

关于黄色标注处:若客户选择AAAA记录从而发送IPv6数据,则不能工作。若选择A记录, 则A记录实际作为一个IPv4映射的IPv6地址返回给客户,使得客户可以发送IPv4数据。
14. 高级IO函数

这两个函数是最重要的函数之一,因为最通用。具体的使用,可以查看vector AP底层网络通信部分的代码。


15. unix域套接字
unix域提供两类套接字:字节流套接字(类似于TCP)和数据报套接字(类似于UDP)。
使用unix域套接字的三个理由:
- 使用socket API,但不经过TCP/IP协议栈,快
- 可以在两个进程之间传递描述符
- 可以传递凭证,是服务器验证客户身份的可靠手段
unix域中用于标识客户与服务器的协议地址是普通文件系统中的路径名(绝对路径)。

socketpair函数可以用于网络服务器中的唤醒工作,除了该方式外,还可以使用管道或者eventfd方案。
指定SOCK_STREAM
的socketpari称为流管道,是全双工通信方式。
注意:因为unix域套接字的地址是一个绝对路径,因此在bind地址之前,一定要确认路径文件是否存在,若存在,一定要先通过unlink
清除路径文件。

16. 非阻塞式IO
Pass
20. 广播


21. 多播
单播地址标识单个IP接口,广播地址标识某子网的所有IP接口,多播地址标识一组IP接口。
广播一般局限于局域网内使用,多播既可以用于局域网,也可以跨广域网使用。
单播使用MAC地址,广播的MAC地址为 FF-FF-FF-FF-FF-FF
,多播的MAC地址为:01-00-5e-0 + 低序23位
,这三者是不同的。
一个进程接收某个多播数据包的先决条件是:该进程加入相应的多播组并绑定相应的端口。


IPv4首部的TTL字段兼用作多播范围字段。
- 0:接口局部,不能由接口输出
- 1:链路局部,不可由路由器转发
- 其他不再赘述,看图

关于不完备过滤与完备过滤:目前多播地址是224.0.0.1
,若有一个多播地址225.0.1.1
发送数据。由于多播地址组ID的高5位在到以太网地址的映射中被忽略,该主机的接口也将接收目的以太网地址为01:00:5e:00:01:01
的帧。因此在数据链路层无法过滤掉,所以说数据链路层是不完备过滤。这种情况下,该帧承载的分组将在IP层完备过滤,IP层会比较该地址与本机接收应用进程已经加入的所有多播地址,根据结果是接收还是丢弃。因此该分组将被丢弃。

多播套接字选项:采用getsockopt
或setsockopt
,相关选项如下:


如果发送UDP多播之前,没有指定影响发送的多播套接字选项,那么UDP的外出接口将有内核选择,TTL或跳限将为1,并有一个副本自环回来。
附录A
IP层提供无连接不可靠的数据报递送服务。
IP层最重要的功能之一是路由。
IPv4首部最大长度为60字节,固定部分20字节,选项部分,最长40字节。
协议字段中,1代表ICMPv4、2代表IGMPv4、6代表TCP、17代表UDP。

IPv6首部最大长度为40字节,没有选项。
下一个首部:6代表TCP、17代表UDP、58代表ICMPv6等
跳限类似于IPv4中的TTL


