总结《Linux高性能服务器编程》1-4章
第一章 TCP/IP协议族
TCP/IP协议族体系结构以及主要协议
- 数据链路层、网络层和传输层负责处理==网络通信细节,这部分必须既稳定又高效,因此在内核空间中实现,应用层则在用户空间实现,因为它负责处理众多逻辑,比如文件传输、名称查询和网络管理等;
-
垂直的实线箭头表示TCP/IP协议族各层之间的实体通信(数据包确实是沿着这些线路传递的),而水平的虚线箭头表示逻辑通信线路;
-
数据链路层
-
数据链路层实现了网卡接口的网络驱动程序;
-
ARP协议(Address Resolve Protocol,地址解析协议)和RARP协议(逆地址解析协议)实现了IP地址和机器物理地址(通常是MAC地址,以太网、令牌环和802.11无线网络都使用MAC地址)之间的相互转换。
-
-
网络层
-
网络层实现数据包的选路和转发,且对上层协议隐藏了网络拓扑连接的细节;
-
IP协议根据数据包的目的IP地址来决定如何投递它;
-
ICMP协议是IP协议的重要补充,用于检测网络连接,ICMP报文包括两种类型;
- 差错报文:用来回应网络错误;
- 查询报文:用来查询网络信息;
- ICMP协议并非严格意义上的网络层协议,因为它使用处于同一层的IP协议提供的服务;
- 差错报文:用来回应网络错误;
-
-
传输层
-
传输层为两台主机上的应用程序提供端到端(end to end)的通信;
-
TCP协议(Transmission Control Protocol,传输控制协议)为应用层提供可靠的、面向连接的和基于流(stream)的服务;
-
UDP协议(User Datagram Protocol,用户数据报协议)为应用层提供不可靠、无连接和基于数据报的服
务; -
SCTP协议(Stream Control Transmission Protocol,流控制传输协议)是一种相对较新的传输层协议,它为在因特网上传输电话信号而设计;
-
-
应用层
-
ping是应用程序,而不是协议,它利用ICMP报文检测网络连接,是调试网络环境的必备工具;
-
telnet协议是一种远程登录协议,它使我们能在本地完成远程任务;
- 能够执行telnet命令并不代表系统中安装了telnet服务,可用netstat -tnl查看是否有进程正在监听本地23端口;
#大部分情况下,我们只是使用它查看目标主机是否打开了某端口 #其执行结果有两种: telnet: connect to address 101.199.97.65: Connection refused #端口未打开 Connected to 10.88.11.25. #端口已打开
-
OSPF(Open Shortest Path First,开放最短路径优先)协议是一种动态路由更新协议;
-
DNS(Domain Name Service,域名服务)协议提供机器域名到IP地址的转换;
host
命令:使用DNS协议和DNS服务器通信,查询目标主机IP地址;- 使用tcpdump观察DNS通信过程;
terminal 1:$sudo tcpdump -i ens33 -nt -s 500 port domain #开启tcpdump抓包,使用“port domain”来过滤数据包,表示只抓取使用domain(域名)服务的数据包; #使用-s 500限制只抓500kB的数据;使用-n表示显示IP地址而不是主机名;使用-t不显示时间戳 terminal 2:$host-t A www.baidu.com #terminal 2即会显示DNS查询和应答报文
-
应用层协议(或程序)可能跳过传输层直接使用网络层提供的服务;
-
封装与分用
-
应用程序数据在发送到物理网络上之前,将沿着协议栈从上往下依次传递。每层协议都将在上层数据的基础上加上自己的头部信息(有时还包括尾部信息),以实现该层的功能;
- 经过数据链路层封装的数据称为帧(frame),帧的最大传输单元(Max Transmit Unit,MTU),即帧最多能携带多少上层协议数据(比如IP数据报),通常受到网络类型的限制;
-
当帧到达目的主机时,将沿着协议栈自底向上依次传递,各层协议依次处理帧中本层负责的头部数据,以获取所需的信息,并最终将处理后的帧交给目标应用程序;
- 以太网帧用2字节标识上层协议:0x800为IP数据报,0x806为ARP;
- IP数据报的头部采用16位的协议(protocol)字段标识上层协议:ICMP协议、TCP协议和UDP协议;
- TCP和UDP数据报的头部采用16位的端口号(portnumber)字段来区分上层应用程序:53为DNS,80为HTTP;
socket和TCP/IP协议族的关系
- 数据链路层、网络层、传输层协议是在内核中实现的,因此操作系统需要实现一组系统调用,使得应用程序能够访问这些协议提供的服务;
- **socket就是实现这组系统调用的一个API(**ApplicationProgramming Interface,应用程序编程接口);
- 由socket定义的API提供两点功能:用户缓冲区和TCP/UDP内核缓冲区之间的数据交互,以及修改内核中各层协议的信息以控制底层通信行为;
- socket是一套通用网络编程接口,它不但可以访问内核中TCP/IP协议栈,而且可以访问其他网络协议栈;
第二章 IP协议详解
IP协议特点
- IP协议是TCP/IP协议族的动力,它为上层协议提供无状态、无连接、不可靠的服务:
- 无状态(stateless:IP通信双方不同步传输数据的状态信息,因此所有IP数据报的发送、传输和接收都是相互独立、没有上下文关系的,简洁高效,但无法处理乱序和重复;
- 无连接(connectionless):IP通信双方都不长久地维持对方的任何信息;
- 不可靠:IP协议不能保证IP数据报准确地到达接收端,它只是承诺尽最大努力;
IP分片
-
以太网帧的MTU是1500字节,因此它携带的IP数据报的数据部分最多是1480字节(IP头部
占用20字节),当IP数据报的长度超过帧的MTU时,它将被分片传输; -
可以通过
ifconfig
命令或者netstat
命令查看以太网帧即IP地址等;
IP路由
-
使用
route
命令或netstat
命令查看路由表; -
IP路由机制的步骤:
- 查找路由表中和数据报的目标IP地址完全匹配的主机IP地址,若无则转2;
- 查找路由表中和数据报的目标IP地址具有相同子网的网络IP地址,若无则转3;
- 选择默认路由项,通常意味着数据报的下一跳路由是网关;
-
更新路由表:
- 通过route命令或其他工具手动修改路由表,是静态的路由更新方式
- 对于大型的路由器,通常通过BGP、RIP、OSPF等协议动态更新路由表;
- ICMP重定向报文也能用于更新路由表,一般来说,主机只能接收ICMP重定向报文,而路由器只能发送ICMP重定向报文;
IPV6
- IPv4用32位表示IP地址,一般用点分十进制来表示;
- IPv6用128位(16字节)来表示IP地址,总量达到
2
128
2^{128 }
2128个,一般用十六进制字符串表示;
- IPv6协议并不是IPv4协议的简单扩展,而是完全独立的协议;
- 增加了多播和流的功能,引入自动配置功能,增加了专门的网络安全功能等;
第三章 TCP协议详解
TCP服务特点
-
面向连接、字节流和可靠传输
- 面向连接:一对一,所以基于广播和多播(目标是多个主机地址)的应用程序不能使用TCP服务;
- 字节流:通信双方不需要执行相同次数的读、写操作;
- 当发送端应用程序连续执行多次写操作时,TCP模块先将这些数据放入TCP发送缓冲区中,当TCP模块真正开始发送数据时,发送缓冲区中这些等待发送的数据可能被封装成一个或多个TCP报文段发出;
- 相反,发送端应用程序每执行一次写操作,UDP就将其封装成一个数据报并发送,因此接收端必须及时针对每一个UDP数据报执行读操作=,否则就会丢包;
- 可靠传输:应答机制与超时重传机制;
TCP头部结构
TCP 连接的建立和关闭
-
使用tcpdump观察TCP连接的建立和关闭
terminal 1 $ sudo tcpdump -i ens33 -nt '(src 192.168.111.170 and dst 14.215.177.38 or src 14.215.177.38 and dst 192.168.111.170)' termial 2 $ telnet 14.215.177.38 80 # 使用telnet建立TCP连接
TCP状态转移
-
TCP状态转移总图
-
粗虚线表示典型的服务器端连接的状态转移,粗实线表示典型的客户端连接的状态转移
-
服务器端连接状态:LISTEN状态、ESTABLISHED状态、CLOSE_WAIT状态、LAST_ACK状态;
-
客户端连接状态:SYN_SENT状态、ESTABLISHED状态、FIN_WAIT_1状态、FIN_WAIT_2状态、CLOSE_WAIT状态、TIME_WAIT状态;
-
-
TIME_WAIT状态
-
TIME_WAIT状态存在的原因:可靠地终止TCP连接,保证让迟来的TCP报文段有足够的时间被识别并丢弃;
-
TIME_WAIT等待一段长为2MSL(Maximum Segment Life,报文段最大生存时间),坚持2MSL时间能够确保网络上两个传输方向上尚未被接收到的、迟到的TCP报文段都已经消失;
-
服务器端由于使用知名端口号,所以TIME_WAIT状态会影响重启,但客户端一般使用系统自动分配的临时端口号来建立连接,所以一般可以立即重启;
-
复位报文段
- 在某些特殊条件下,TCP连接的一端会向另一端发送携带RST标志的报文段,即复位报文段,以通知对方关闭连接或重新建立连接;
- 产生原因:访问不存在的端口、异常终止连接、处理半打开连接;
TCP数据流
- TCP报文段所携带的应用程序数据按照长度分为两种:交互数据和成块数据;
- 交互数据:仅包含很少的字节,交互数据的应用程序(或协议)对实时性要求高,比如telnet、ssh等;
- 成块数据:长度则通常为TCP报文段允许的最大数据长度,对传输效率要求高,比如ftp;
带外数据
- 带外(Out Of Band,OOB)数据:用于迅速通告对方本端发生的重要事件,优先级更高;
- UDP没有实现带外数据传输,TCP也没有真正的带外数据;
- TCP利用其头部中的紧急指针标志和紧急指针两个字段,给应用程序提供了一种紧急方式;
TCP超时重传
- TCP模块为每个TCP报文段都维护一个重传定时器,该定时器在TCP报文段第一次被发送时启动;
- 如果超时时间内未收到接收方的应答,TCP模块将重传TCP报文段并重置定时器;
拥塞控制
-
基本概念
-
四个部分:慢启动(slow start)、拥塞避免(congestion avoidance)、快速重传(fast retransmit)和快速恢复(fastrecovery);
-
拥塞控制算法在Linux下有多种实现,比如reno算法、vegas算法和cubic算法等;
-
一些概念:
- 发送窗口(SWND,SendWindow ):发送端向网络一次连续写入的数据量;
- 发送者最大段大小(SMSS,Sender Maximum Segment Size):TCP报文段的最大长度(仅指数据部分),受限于SWND,一般等于MSS;
- 接收通告窗口(RWND);
- 拥塞窗口(Congestion Window,CWND);
- 慢启动门限(slow start threshold size,ssthresh);
-
发送端需要合理地选择SWND的大小,如果SWND太小,会引起明显的网络延迟;反之,如果SWND太大,则容易导致网络拥塞;
- 实际的SWND值是RWND和CWND中的较小者;
-
-
慢启动和拥塞避免
-
快速重传和快速恢复
- 发送端如果连续收到3个重复的确认报文段,就认为是拥塞发生了。然后它启用快速重传和
快速恢复算法来处理拥塞;
- 发送端如果连续收到3个重复的确认报文段,就认为是拥塞发生了。然后它启用快速重传和
第四章 TCP/IP通信案例:访问Internet上的Web服务器
-
代理服务器
-
在HTTP通信链上,客户端和目标服务器之间通常存在某些中转代理服务器,它们提供对目标资源的中转访问;
-
代理服务器按照其使用方式和作用,分为正向代理服务器(客户端)、反向代理服务器(服务器端)和透明代理服务器(网关);
-
-
通信内容
- 代理服务器访问DNS服务器以查询域名对应的IP地址;
- 代理服务器查询路由器MAC地址的ARP请求和应答;
- wget客户端(192.168.1.109)和代理服务器(192.168.1.108)之间的HTTP通信;
- 代理服务器和Web服务器(119.75.218.77)之间的HTTP通信;
-
HTTP通信
-
HTTP请求
GET http://www.baidu.com/index.html HTTP/1.0 User-Agent:Wget/1.12(linux-gnu) Host:www.baidu.com Connection:close “GET”是请求方法 “http://www. baidu.com/index.html”是目标资源的URL “http”是所谓的scheme,表示获取目标资源需要使用的应用层协议,其他常见scheme还有ftp/file等 “www.baidu.com”指定资源所在的目标主机 “index.html”指定资源文件的名称 “HTTP/1. 0”表示客户端(wget程序)使用的HTTP的版本号是1.0 HTTP请求内容中的第2~4行都是HTTP请求的头部字段,在空行之后,HTTP请求可以包含可选的消息体
-
HTTP应答
HTTP/1.0 200 OK Server:BWS/1.0 Content-Length:8024 Content-Type:text/html;charset=gbk Set-Cookie:BAIDUID=A5B6C72D68CF639CE8896FD79A03FBD8:FG=1;expires=Wed,04- Jul-42 00:10:47 GMT;path=/;domain=.baidu.com Via:1.0 localhost(squid/3.0 STABLE18) “200 OK”是状态码和状态信息 第2~7行是HTTP应答的头部字段 空行之后是被请求文档index.html的内容
- Cookie是服务器发送给客户端的特殊信息,客户端每次向服务器发送请求的时候都需要带上这些信息,服务器通过这种方式可以区分不同的客户;
-