- TCP/IP模型
- IP
- TCP/UDP
- 0 表示标准输入,对应Java中的stdin
- 1 表示标准输出,对应Java中的stdout
- 2 表示标准错误输出,对应Java中的stderr
- 0/1/2 其实是在进程目录的fd目录下的3个fd
- 1> 表示标准输出重定向,可简写为 >
- 0< 表示标准输入重定向,可简写为 <
- 一般 <或> 后面跟的是文件名表示直接对接文件
- 也可在 <或> 后面紧跟一个 & 表示对接到另一个fd,如 2 >&1
- $$ 表示当前shell进程号
- exec 表示等待一个命令来替换当前的shell,如果没有命令则不会退出当前shell
- exec N<> /dev/tcp/wwww.baidu.com/80 #表示创建一个socket,fd为N
- echo -e “GET / HTTP/1.1 \r\n” 1>&N #表示写入fd为N的socket
- cat 0<&N #表示查看fd为N的socket
- exec N>& - #表示销毁fd为N的socket
- 常见协议
TCP/IP模型
Transmission Control Protocol/ Internet Protocol 传输控制协议/网络协议,是Internet的核心协议。
Open System Interconnection 开放式系统互联
OSI网络通信模型 | TCP/IP网络通信模型 |
---|---|
应用层(进程间通信) | 应用层(HTTP/SSH等) |
表示层(序列化反序列化/解压缩/加解密) | |
会话层(访问验证和会话管理) | |
传输层(数据包packets即TCP的segments段和UDP的datagrams数据报) | 传输层(TCP/UDP) |
网络层(路由器等关注网间路由/IP) | 网络层(IP/ICMP) |
数据链路层(网桥/交换机等关注MAC路由表,上层数据加头尾封装成帧) | 数据链路层(ARP) |
物理层(网线/网卡/集线器等) |
IP
网络号和主机号
- 两台计算机要通信,首先要判断是否处于同一个广播域内,即网络地址是否相同
- 如果网络地址相同,表明接收方在本网络,可以直接把包发给目标主机
- 如果网路地址不同,表明跨网络,需要路由器进行路由
- 路由器寻址的工作中,也是通过这样的方式找到对应的网络号,进而把数据包转发给对应的网络
IP版本
IPv4
地址长度共32位,每8位作为1组,分为4组,点分十进制表示,每组最大值255
IPv6
地址长度是128位,每16位作为1组,分为8组,冒分十六进制,每组最大值FFFF
- 如果出现连续的0时还可以把0省略掉,并用两个::隔开
-
IP分类
32位的IP地址分为网络位和主机位,目的是为了减少路由表的记录数,同一个网络地址只需一条记录
最大主机数要看主机位的个数n,算得
2```` - 2
,减去的2作用如下
IP分类的不足
- 同一网络下没有地址层次,缺少灵活性
- 比如需要根据环境(测试、生产)来划分层次就不支持
ABC类不能很好的与现实匹配
Classless Inter Domain Routing 无类域间路由
不再有分类地址的概念,32比特的IP地址被划分为两部分,前面是网络号,后面是主机号,使IP更灵活
a.b.c.d/x
表现形式1: a.b.c.d/x,其中x表示前x位为网络号,x的范围0-32
子网掩码
- 表现形式2:子网掩码
- 掩码的意思是掩盖掉主机号,剩余的就是网络号
- 将子网掩码和IP地址按位计算 AND,即可得到网络号
- 子网掩码作用
- 计算网络
- 划分子网
- 将原本的主机地址再分为2个部分
- 子网网络地址
- 子网主机地址
- IP地址根据子网掩码划分子网后,由原来的主机位从左到右借位作为子网的网络地址位
- 借了多少位(n)就被划分为2个子网,比如借了2位就被划分位 00、01、10、11四个子网
- 将原本的主机地址再分为2个部分
公有IP和私有IP
环回地址
- 环回地址是在同一计算机上的不同程序之间进行网络通信时使用的默认地址
- 127.0.0.1这个特殊IP作为环回地址,与该地址具有相同意义的是一个localhost的主机名
使用127.0.0.1或localhost时数据包不会流向网络
IP协议头
TTLTime To Live
- 表示这个ip包穿过多少个路由后会被抛弃,每穿过1个路由就会-1,0就抛弃
- 8位的最大值为255,所以一个包最大穿255个路由
- 根据系统不同这个数字不一样,一般是32或64
相关协议
- ARP
- 根据IP地址获取MAC
- 主机原本不知道IP对应哪个MAC,发送数据前首先查询ARP高速缓存表
- 如果存在就使用,不存在就向网络发送ARP广播包(包里包含IP地址)
- 网络内每个主机收到广播包后进行识别,符合条件的响应一个包含自己MAC的ARP包
- 主机拿到响应后更新自己的缓存表,并发送数据
ICMP
路由表中记录着网络地址与下一步应该发送至路由器的地址,在主机和路由器上都有各自的路由表
- 当需要访问外部系统时,用外部系统IP和Genmask做与运算,从上到下看是否能匹配Destination
- 如果匹配则走对应的Gateway,Gateway为0.0.0.0则表示在同一网络,不需要走网关
- 如果匹配多条,则选择相同位数最多的网络地址,也就是最长匹配
- 如果不匹配则则匹配下一条,直到主机不可达
数据链路层
# arp -a
? (192.168.150.1) at xx:xx:xx:xx:xx:xx [ether] on eth0
# arp -d IP
- IP包走到数据链路层就会封装对应下一跳的MAC地址,转发给网关
- 网关解开包后看到目的IP,在自己的路由表中进行匹配转发
-
常用工具
ping 监测主机是否可达
- traceroute 监测主机与目标之间的路由情况,就是利用TTL不断递增和ICMP的报错机制实现
- tcpdump 抓网络包
# tcpdump -nn -i eth0 port 80 or arp
TCP/UDP
协议特点
| | TCP | UDP | | —- | —- | —- | | 可靠性 | 可靠 | 不可靠 | | 连接性 | 面向连接 | 无连接 | | 报文 | 面向字节流 | 面向报文 | | 效率 | 传输效率低 | 传输效率高 | | 双工性 | 全双工 | 一对一、一对多、多对一、多对多 | | 流量控制 | 滑动窗口 | 无 | | 拥塞控制 | 慢开始、拥塞避免、快重传、快恢复 | 无 | | 传输速度 | 慢 | 快 | | 应用场景 | 效率低、准确率高 | 效率高、准确性低 | | 应用层协议 | TELNET、HTTP、FTP、SMTP | DNS、TFTP、SNMP、NFS | | 应用 | 远程终端接入、万维网、文件传输、电子邮件 | 域名转换、文件传输、网络管理、网络文件服务 |
TCP包头
窗口
- 滑动窗口进行流量控制
- 滑动窗口即TCP接收缓冲区的大小
可选的选项部分
- 最大报文长度,通常为MTU-40字节(IP头的20个字节和TCP头的20个字节)
- MTU是以太网链路的标准传输单元大小
TCP连接
三次握手
因为TCP面向连接,数据发送前必须建立连接,目的同步连接双方的序列号和确认号并交换TCP窗口大小信息。
原因
- 双方都需要确认自己的发送和接收功能正常,保证可靠性
-
四次挥手
TIME_WAIT
等待2倍MSL
- Maximium Segment Lifetime数据在网络内最长存活时间
- RFC规定MSL是2分钟,实践中可设置30s/1min/2mins
- 等待2倍原因
- 保证TCP协议的全双工连接能够可靠关闭,不用重复发送FIN
- 保证这次连接的重复数据段从网络中消失,防止新老两个连接建立在同一个端口上导致残留数据的穿越
TCP流量控制
- 控制发送速率不要太快,防止接收方来不及接收造成数据的丢失。
主要通过滑动窗口rwnd(ReceiverWindow)控制
发送方维持一个拥塞窗口cwnd(CongestionWindow)的状态变量
- 拥塞窗口cwnd的大小取决于网络的拥塞程度并动态变化
发送方让自己的发送窗口等于拥塞窗口并逐步增大,一旦出现拥塞就开始减少
慢开始算法
由于一开始不清楚网络负荷,一般是由小到大逐渐探测。
- 通常开始时把cwnd设置为一个最大报文段MSS的值,即cwnd=1
- 在每收到一个报文段的确认后逐步增加一倍
防止cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量
cwnd缓慢增大,每经过一个往返时间RTT就加1,而不是加倍
- 拥塞出现的依据就是没有收到确认
- 拥塞出现后要把ssthresh设置为发送窗口值的一半,但不能小于2,同时把cwnd设置为1,执行慢开始算法
目的就是迅速减少主机发送到网络中的分组数,使发生阻塞的路由器有足够时间把队列中挤压的分组处理完毕
快重传
接收方每收到一个失序的报文段后就立即发送重复确认,目的是使发送方及早知道有报文段没有到达对方
- 发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,不必等到该报文段计时器到期
- 采用该算法(尽早重传未被确认的报文段)可使整个网络的吞吐量提高约20%
快恢复
- 当发送方连续收到三个重复确认,就执行“乘法减小”算法,把慢开始门限ssthresh减半。
- 把cwnd值设置为ssthresh减半的值,然后开始执行拥塞避免算法“加法增大”,使拥塞窗口缓慢的线性增大。
相关概念
- VLAN
- 虚拟局域网,特指使用路由器分割的网络
- 同一个VLAN间可相互通信
- 不同VLAN间通信,必须要有路由功能
- 单臂路由:普通二层交换机加路由器,路由器不通WLAN,可应付小型网路,大型网络路由器是瓶颈
- 三层交换机:本质就是带有路由功能的二层交换机(内置了交换模块和路由模块,内部是汇聚链接,可实现高速路由)
- 网关
- 网间连接器,在传输上实现网络互联
- 实际是一个网络通向另一个网络的IP地址,一般用网段内的第一个IP
- 即使是两个网络连在同一台交换机上,如果是不同网段也不能通信,因为TCP/IP会根据子网掩码计算
- 默认网关就是找不到可用的网关后都要把数据发给的网关
SOCKET实践
socket是源IP:源Port 目标Ip:目标Port组成的一条通信连接。
netstat -natp 看到的每一条记录都是一个socket。
数据包大小:MTU(1500)- IP/TCP固定头部长度(20 + 20) = 通常长度(1460) ```bash0 表示标准输入,对应Java中的stdin
1 表示标准输出,对应Java中的stdout
2 表示标准错误输出,对应Java中的stderr
0/1/2 其实是在进程目录的fd目录下的3个fd
1> 表示标准输出重定向,可简写为 >
0< 表示标准输入重定向,可简写为 <
一般 <或> 后面跟的是文件名表示直接对接文件
也可在 <或> 后面紧跟一个 & 表示对接到另一个fd,如 2 >&1
$$ 表示当前shell进程号
exec 表示等待一个命令来替换当前的shell,如果没有命令则不会退出当前shell
exec N<> /dev/tcp/wwww.baidu.com/80 #表示创建一个socket,fd为N
echo -e “GET / HTTP/1.1 \r\n” 1>&N #表示写入fd为N的socket
cat 0<&N #表示查看fd为N的socket
exec N>& - #表示销毁fd为N的socket
cd /proc/$$/fd exec 9<> /dev/tcp/www.baidu.com/80 echo -e “GET / HTTP/1.1 \r\n” 1>&9 cat 0<&9 exec 9>& -
<a name="cmOq1"></a>
## TCP实践
<a name="uDgCZ"></a>
### TIME_WAIT
- 端口上限65535(16bit/2Byte)
- 当有大量连接处于TIME_WAIT时,新建立TCP连接会出错`address already in use: connect异常`
```shell
# 统计TCP连接状态的数量
netstat -n | awk '/^tcp/ {++S[$NF]} END{for(a in S) print a,S[a]}'
- 出现大量TIME_WAIT本质原因
- 大量短连接,HTTP请求connection头部值为close时,基本由服务端主动关闭连接
- TCP四次挥手关闭连接时,为了保证ACK重发和丢弃延迟数据,TIME_WAIT一般为2MSL,即4mins
- 一般解决方法
- 客户端请求的connection头部值为keep-alive
- 服务端
- 允许TIME_WAIT状态的socket被重用
- 缩减TIME_WAIT时间,可设置为1MSL,即2mins
常见协议
DNS
流程图
- 解析时一般按如下流程:
- DNS缓存
- 系统缓存
- 本地HOSTS文件
- 本地DNS
相关概念
- 本地DNS服务器
- 就是设备上配置的DNS地址
- 根域DNS服务器
- 根域DNS服务器保存在互联网上所有的DNS服务器中,任何DNS服务器都可访问
- 任何DNS请求都可由此处查询开始,逐级确认
- 顶级域DNS服务器:
- .com .cn 等的顶级域服务器
- 可以查询对应的权威服务器地址并返回,比如 domain.com
权威DNS服务器
传输数据包时,确定了源IP地址/目标IP地址后,就通过路由表确定IP数据包的下一跳
- 网络层的下一层是数据链路层,所以还要知道下一跳的MAC地址
- 通过下一跳的IP地址获取MAC地址就可通过ARP协议进行
- 简单的就是借助ARP请求和ARP响应包确定MAC地址,通过子网的广播包进行通信
- 操作系统通常会把第一次获得的MAC地址缓存起来,超过缓存期限再把缓存清除
RARP
- 和ARP相反,通过MAC地址求IP地址
- 常用于嵌入式设备如打印机服务器接入网络时
- 通常需要架设一台RARP服务器,其他设备在这个服务器上注册MAC和IP地址
DHCP
流程图
步骤详解
- DHCP客户端进程监听68端口,DHCP服务端进程监听67端口
- 客户端发起DHCP发现报文(DHCP DISCOVER),由于客户端没有IP,也不知道DHCP服务器的地址,所以使用UDP的广播通信,广播目的地址255.255.255.255:67,本地地址0.0.0.0:68
- DHCP服务器收到DHCP发现报文,进行DHCP提供报文(DHCP OFFER)的响应,该响应仍然使用广播,报文内容携带可租约的IP地址、子网掩码、默认网关、IP地址租用期、DNS服务器
- 客户端收到一个或多个DHCP OFFER后,从中选择一个,并发送DHCP请求报文(DHCP REQUEST)请求配置参数
- 最后服务端用DHCP ACK报文进行响应,应答请求的参数
- 租期内可一直使用,快过期时客户端会向服务器发送请求报文进行续约
- 服务器如果同意则回应DCHP ACK,如果不同意则回应DHCP NACK
交互全程使用UDP协议广播通信,为了解决客户端和服务器不在同一个局域网而路由器又不转发广播包的问题就出现了DHCP中继代理,可以使不同网段的IP地址分配可以由一台DHCP服务器统一进行
中继代理
客户端向中继代理发送DHCP请求包,而DHCP中继代理收到这个请求的广播包后再以单播的形式发给DHCP服务器
- 服务器收到后再响应给DHCP中继代理,DHCP中继代理再转发给客户端
NAT/NAPT
NAT
- 网络地址转换
- 缓解IPv4地址快速耗尽的问题
- 简单来说就是在同个局域网内的主机对外通信时,把私有IP地址转换为公有IP地址
NAPT
- 把IP地址和端口号一起进行转换,网络地址和端口转换
不足
- NAT/NAPT都依赖自己的转换表,转换表的产生和转换操作都会产生性能开销
通信过程中,如果NAT路由器重启了,所有的TCP连接都要重置
解决方案
改用IPv6
- 范围非常大,不用转换
- 但普及还需要一段时间
NAT穿透技术
Internet Control Message Protocol 互联网控制报文协议
当遇到网络问题时,需要传出消息,报告遇到了什么问题,这样才能调整策略,来控制整个局面
功能
确认IP包是否成功送达目标地址
- 报告发送过程中IP包被废弃的原因和改善网络的设置等
类型
- 查询报文类型,用于诊断的查询消息
- 差错报文类型,通知出错原因的错误消息