Linux 服务器编程学习笔记①
# 计算机网络知识复习(查漏补缺)
# 协议栈
因特网五层协议栈:
应用层属于用户空间,运输层及以下属于内核空间,其间由socket进行交流。
七层OSI模型:
因特网中的应用层是将此模型中的应用层、表示层、会话层结合后的协议层。而在此模型中应用层为应用提供借口;表示层为数据传输进行格式兼容和含义解释;会话层负责设置并维护两台计算机之间的通信连接。
封装和分用是上下层协议间进行转换的过程。
- 封装,上层协议向下层协议传递时,在数据头部加上自己的头部信息并将其一起作为数据传递给下层协议。
- 分用,下层协议向上传递时,根据头部中的相关字段将数据包交给相应的协议或者应用程序。
# ARP协议
ARP协议实现了任意网络层地址到任意物理地址的转换。其向自己所在的网络广播一个ARP请求(其中包含了目标机器的网络地址),网络中只有网络地址与之匹配的机器会发送ARP应答(其中包含了其的物理地址),最后请求方便可知晓对应网络地址机器的物理地址。
为了提高发送数据包的效率,ARP维护了一个高速缓存,在Linux下可通过 arp
命令对其进行查看和修改。
RARP协议则与之相反,实现了IP地址和机器物理地址的转换,主要用于无存储功能的设备且管理者存储了其相关映射的特殊情况。
# 令牌环网 (Token Ring)
一段特殊帧作为令牌在令牌环网上传递,拥有令牌的站点才能发送数据(将令牌置为忙),其他站点则检查数据是否发送给自己,是则收下并发给下家,否则直接发给下家,最终数据回到发送站点,若检查无误则一次发送结束。通常,一个站点拿到令牌后发送数据的时间是一个定值,到时后站点将令牌置为空闲,然后发送给下家。
# ICMP 重定向
当路由器检测到一台机器使用非优化路由时,会向其发送一个 ICMP 重定向报文,请求其变更为更优化的路由,并且同时也会执行本次非优化的路由。这是提高路由效率的一种方法。
以下两种情况会引发路由器发送 ICMP 重定向报文:
- 当路由器从某个接口收到数据还需要从相同接口转发该数据时;
- 当路由器从某个接口到发往远程网络的数据时发现源ip地址与下一跳属于同一网段时。
# TCP 相关
TCP 基于字节流,而 UDP 基于数据报。
TCP 连接由一对 ip 地址 + 端口号(2 字节 16 位) 组成。
# TCP 连接建立与关闭
上图展示了一般情况的连接建立与关闭。连接建立通过三次握手(本质上其实也是四次握手),而关闭时则是四次挥手。
三次握手建立连接的目的:在不可靠信道中进行可靠连接的建立,则必须确保通信对方已经收到了之前我方提出的连接请求以及初始变量(主要包括 TCP 连接中的序号等)。这样实际上有四步,只是对方可以将对我方信息的确认报文和其自身发送的用于建立连接的变量报文合并在一起,这样形成了三次握手,同时也确认了双方通信的可正常进行(我方即可发送也可接收,对方也即可发送也能接收)。最后,由于 TCP 连接中序号的随机生成以及对序号的确认机制,使得三次握手也避免了之前已失效的 SYN 报文对本次连接建立造成的影响。
四次挥手关闭连接则是上一段中第一句话的原本形态。由于 TCP 是全双工的,所以当一方关闭连接后,数据仍然可以从未关闭连接的一方发送到关闭了连接的一方,此时处于半关闭状态。待数据传输完毕,未关闭的一方便可关闭此方的连接,最终整个 TCP 连接就被关闭了。但是上面讲的此类情况比较少,由于 TCP 的延时确认机制,使得图中报文段 5 和报文段 6 可以一起发送,这样便变成了和三次握手类似的情况(可以称之为三次挥手吗?)。
# TCP 状态转移图
上图中粗实线为一般情况下客户端的状态转移路径(连接发起方),虚线是服务端的状态转移路径(被连接方)。
客户端中在 CLOSED 关闭状态前有一个 TIME_WAIT 状态。此状态用于:
可靠地终止 TCP 连接。
保证网络中与此连接相关的报文段都消失(超过最大生存时间)。
当一个新连接请求建立的端口号正在被另一个连接使用时或者是我方的端口已经关闭连接时,计算机会发送复位报文段告知对方错误。
所以,针对上述作用1,若没有 TIME_WAIT 状态我方机器直接关闭,那么如果最后发送的 ACK 报文未抵达对方,对方认为是自己的 FIN 报文丢失,根据 TCP 规则进行重传而此时由于我方机器已关闭连接释放资源,故我方发送复位报文段,对方则会收到此错误信息,而无法进行正常关闭。而加入了 TIME_WAIT 状态后,我方机器便可以收到重复的 FIN 报文,从而知晓我方发送的 ACK 报文丢失,进而重新进行发送。
针对上述作用2,若没有 TIME_WAIT 状态我方机器直接关闭,那么有可能此时另一个新连接在此端口上建立起来了,而由于网络拥塞,此时有一批旧连接的报文到达我方主机,我方主机会误认为这批报文是新连接的报文,从而发生逻辑错误。而加入了 TIME_WAIT 状态后,相当于我方主机等待了报文段在网络中所能存活的最长时间(实际上还要长),若有因为网络拥塞而延迟到达的报文,其也可以在 TIME_WAIT 状态内到达,而不会造成后续连接的逻辑错误。
# TCP 交互数据流
对实时性要求较高、数据量较少的情况下,可以使用 TCP 的 Nagle 算法,其要求 TCP 在任意时刻只能有一个未确认报文(相当于一个一个报文地发送),并在等待确认的同时把此时段内的数据收集在一起,使用下一次的报文打包发送。
这类方法的优点便是自适应性强,确认越快,发送越快,还避免了大量微小数据包造成网络拥塞的风险。
# TCP 成块数据流
即我们平时最常使用的 TCP 。通过滑动窗口、接收窗口、拥塞窗口等机制进行拥塞控制的模式。注意可通过 PSH 标志告知对方尽快读取数据,而非等待未到达的数据。
# TCP 带外数据
TCP 没有真正的带外数据发送过程, 而是通过设置紧急指针在普通数据包中加入了紧急数据,并设置 URG 标志,告诉对方有紧急数据,对方变会将紧急指针处的数据读入带外缓存(只有一个字节),并且后续紧急数据有可能覆盖此缓存。
# HTTP 常见状态码
# 网络相关文件
# /etc 配置文件
/etc/services 所有知名应用层协议端口
/etc/protocols 定义了 ip 层之上的协议数值
/etc/resolv.conf 存放 DNS 服务器 ip 地址
/etc/hosts 存放主机名与 ip 地址的映射
# /proc 内核文件
/proc/sys/net/ipv4 ipv4 相关功能
例如
ip_forward 是否允许转发数据报
tcp_window_scaling 是否启用 TCP 窗口扩大因子
tcp_sack 是否启用选择性确认 (SACK)
tcp_timestamps 是否启用时间戳
tcp_syn_retries TCP 超时重连次数
tcp_congestion_control TCP 使用的拥塞控制算法
conf/all/send_redirects 是否允许发送 ICMP 重定向报文
conf/all/accept_redirects 是否允许接收 ICMP 重定向报文