udp 🔗
光速:30万千米/s
中美具体大约:1.5万千米
光纤网络耗时的理论极值约是:0.05s=50ms
实际耗时在140ms以上。
第一宇宙速度7.9km/s 环绕速度
第二宇宙速度11.2km/s脱离速度
第三宇宙速度16.7km/s逃逸速度
quic 🔗

http2 优点:多路复用,头部压缩,服务器推送。 缺点:基于 tcp 时连接握手,多路复用时存在队头阻塞,丢包后导致后续其他包不可用,优化 tcp 和 tls 遥遥无期。
tcp 🔗
用寄明信片的方式传送一本书
明文, 乱序,丢包
- 可靠: 带重传的累积正向应答
- 编号
- 累计的正向应答(ack number1, number1 之前均收到)
- 超时没收到 ack 则重传。
- flow control 滑动窗口
- congestion control 拥塞控制
tcp 中最主要消耗 cpu 的状态是 established
学的时候教 handshake, byebye status。学车是教倒车入库,但是路上开车是主要点
tcp 报文结构图

- URG: 表示紧急指针(urgent pointer)是否有效
- PSH: 提示接收端应该立即从 TCP 接收缓冲区中读走数据,为接收后续数据腾出空间
- RST:复位报文段,用来关闭异常的 TCP 连接 (重要) (4 种情况会出现: 端口未打开,请求超时,提前关闭,已经的 socket 上收到数据)
- A 想 B 发起 tcp 连接,但是 B 上未监听相应的端口,此时 B 的 os 的网络模块会发送 RST 包给 A 端
- syn 攻击时防火墙设置,向服务器发送 RST 包,清除未连接队列的数据包,保证避免 server 出现拒绝服务的情况
- RST 攻击场景,攻击则伪装为客户端向 server 发送 RST 包,导致连接被强制关闭
- window:是 TCP 流量控制的一个手段, 告诉对方本端的 TCP 接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度(sender 在未收到 ack 时最大发送的字节数)
- checkSum: 校验数据包是否损坏
两个线程如何同时监听一个端口,SO_REUSEPORT 参数
- 4 次挥手: A 和 B 打电话,通话即将结束后,A 说“我没啥要说的了”,B 回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,这样通话才算结束
tcp 握手与挥手过程图(基本图,实际中可以不是这样,例如关闭时双方同时发起关闭,双方都会到达 time_wait 状态)


⚠️ wireshake 上的 seq 和 ack number 是 relative number,0 和 1 是为了方便查看,实际情况是其他数值
TIME-WAIT 状态的理解:
- 持续时间未 2MSL,一个数据包在网络中的最长生存时间为 MSL(30S)
- 客户端回复的 ACK 丢失,服务器端会在超时时间到来时,重传最后一个 FIN 包
- ACK 和 FIN 在网络中的最长生存时间就为 2MSL,这样就可以可靠的断开 TCP 的双向连接
服务器解决 TIME——WAIT(占用端口过多,导致无可用的端口)的方式 3 种:
- 保证客户端主动关闭
- 关闭时使用 RST 方式
- 对于处于 TIME-WAIT 状态的 tcp 允许重用,修改内核参数(java 服务器访问 mysql 集群,主动关闭,time-wait 状态在服务器,他是发起方,可以复用 tcp 连接)
- 当利用 http 发送请求时,keep-alive 减少 tcp 连接数,进而减少 time-wait 状态的出现
TCP 如何实现可靠传输(数据应答机制+数据超时重传)
- 数据包都序列号,保证接收方能恢复数据包的顺序,去重等
- 超时重传(确认和重传), 也有快速重传,不用等待超时时间
- 超时时间大于 RTT(一次往返时间)
- 每个被发送的数据包均有计时器,只有超过计时器的重传时间后,才会重发数据包
- 1988 最早的超时重传 RTO = min(ubound, max(lbound, beta _ SRTT)); SRTT= (alph _ SRTT) + (1- alpha) * RTT ; alpha=0.8, 0.9 beta=1.2, 1.3
- RTO 比 RTT 大很多时,若出现网络丢包,重传速度很慢; RTO 假设比 RTT 小时,会出现大量的重传; 所以 RTO 的时间比较考量
TCP 如何实现流量控制
- 当接受方处理不过来时,接受方缩小窗口,告知发送方
- 以字节为单位的滑动窗口技术
- recv 的窗口大小决定 sender 的窗口大小(窗口以字节为单位)
- sender 缓存中的数据包必须收到 recv 的确认数据包后才能删除
- 当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失
TCP 如何实现拥塞控制
- 当网络拥塞时,动态改变发送窗口大小,减少数据的发送
基于 TCP 的攻击
- SYN 泛洪攻击
- 发送大量的 SYN 包,导致 server 上未连接队列满,导致拒绝正常的连接服务
- 解决方法:
- SYN 网关, 防火墙收到 SYN 包转给 server,防火墙收到 server 的 ack/syn 后,转给 client;同时防火墙以 client 的名义直接给 server 发送 ack,完成 3 次握手。 server 上连接数远大于未连接数。
- 被动式 SYN 网关,防火墙设置小的超时时间,超时时向 server 发送 RST 包,导致关闭半连接
- SYN 中继, 完全有防火墙做代理,防火墙与 client 握手完成表明正常后,在于 server 完成 3 次握手
- RST 攻击 (ip 头+tcp 头 40 字节)
- 场景: A--》B, C(伪装 A)--》B, 发送 RST 包,或者正在连接时发送 SYN 包,B 会清空 A 请求过来的数据包,强制关闭连接
- C 如何伪装 A (tcp 四要素:源 ip(容易知道),源 port,目的 ip(容易知道),目的 port(容易知道))
- 关键是知道源 port(发现 os 分配时的规律)和序列号(需要在 B 的滑动窗口内,不然会被丢弃)
- 大量发送数据包(带宽不是问题,RST 包很小)保证一个落在 B 的滑动窗口内 ,sequence number 为 32 位,滑动窗口为 65535,相除为 65537 个数据包就有一个落在区间内
http 🔗
http header 常用字段:
- content-type (如何解析 body)
- application/x-www-form-urlencoded
- multipart/from-data, 上传文件
- application/json, text/plain
- text/xml, XML 格式 (post 请求的 4 种格式)
- connection: keep-alive, 持久连接(相对于用完就关闭的短连接而言)
- keep-alive-time: 300, 指连接维持的时间
- content-length: 120, 指明响应的内容有 120 字节 (出现等于-1,但是 body 有数据的情况?)
- transfer-encoding: chunked, 响应内容采用分块传输,最后一个分块为 0 表示传输结束
http keep-alive 与 tcp keep alive 区别与联系:http 用于连接复用, tcp 用于保证连接存活,发送探测包确认连接是否存活。
有时 ping url 结果为 unkown host,但是 curl url 可以通, 有可能对方防火墙屏蔽 ping 的 ICMP 协议。
CORS, CSRF 🔗
CORS(跨域资源共享): 一种浏览器安全机制,它允许受信任的域对其他域的资源进行访问。
curl 模拟跨域访问。
curl -H 'Origin: 123' ip:port/uri --verbose 发起跨域 http 请求, 当 http 的响应 header 中出现Access-Control-Allow-Origin: * 时证明后端允许跨域访问。
CSRF(跨站请求伪造): http 的 header 里 referer 过滤跨站点请求。 csrf token。
curl 命令 🔗
发 get 请求: 不带参数 curl xx.com。发 post 请求: curl -X POST xx.com。
-
-I only response header
- curl -I www.google.com
- (curl -I 获取 http 响应的头部)
-
-v 显示 http 通信过程 --trace
- curl -v http://www.example.com/index.html
-
发送的请求, <接收的响应
- RFC2616
-
curl -u username :password URL
-
curl 查询单词
- curl dict://dict.org/d:xxx 查询 xxx 的含义
- curl dict://dict.org/show:db 列出可用的词典
- curl dict://dict.org/d:xx:foldoc 利用 foldoc 查询 xx 的含义
-
给 curl 设置代理
- curl -x proxyserver.test.com:9090 google.com
-
将 cookie 保存到本地
- curl -D localCookie google.com
- curl -b localCookie google.com 使用上次的 cookie
- curl -c cookie url 保存 cookie 到文件
-
默认 curl 使用 get 方式 发送表单
- curl -u username github.com
-
可以通过--data/-d 方式使用 post
- curl -u username --data "param1=value1¶m2=value2" github.com
- curl --data @filename github.com 将文件中的数据传给服务器
-
User Agent (-A , -H)
- curl --user-agent "user-agent" url
-
cookie (-b)
- curl --cookie "name=xx" url
- cookie 值可以从 response header 的·Set-Cookie·字段得到
-
自行加 request header 信息
- curl --header "" url
-
curl -d '{"key1":"value1", "data":{"data1":"value1", "data2":"value2"}}' 'https://xxx.com/a/b'
-
curl -F 'business_type=one' -F 'data=@/Users/kk/a.csv' x.x.x.x:xx/a/b curl 发送文件
-
curl -G -d 'q=xx' xx.com -d ''//xx.com?q=xx
-
ping icmp 协议 封装在 IP 包里
- 类型 0 8 请求与响应
- 3 是不可达 后面有代码号
- 5 种情况
- ip 中的网络号-网络不可达
- ip 中的主机号-主机不可达
- 防火墙不允许 tcp 连接-协议不可达
- 端口没有进程监听-端口不可达
- 5 种情况
dns 🔗
dig 查询 DNS 相关信息的工具,显示 internet 上 13 个根域服务器,dig @dnsserver name querytype,用 google 的 dns 查询 baidu 的 A 记录, dig @8.8.8.8 www.baidu.com A。
- DNS 记录的类型
- A 记录 指定域名对应的 IP 地址
- AAAA 记录 指定域名对应的 IPV6 地址
- CNAME 记录 别名解析 域名 1(CDN 加速域名) -》域名 2 -》IP
- NS 记录 域名服务器记录 将域名解析交给其他 DNS 服务器
访问 github.com 时与 DNS 解析有关的一个问题 🔗
问题:fatal: unable to access 'https://github.com/brettKK/shell.git/': Failed to connect to github.com port 443: Operation timed out
方法:vim /etc/hosts ==> find github.com to delete
网络常用工具命令(文件夹 network) 🔗
- ss = socket statistics
- 用来显示处于活动状态的套接字信息
- 快,利用到了 TCP 协议栈中 tcp_diag
- ss -t 显示 tcp 连接
- nc 网络发包工具
- netstat
- netstat -an
- tcpdump
常见命令:
#netstat -antp [n是ip显示,不用域名,t是tcp, ]
recv-q, send-q。
#cat /proc/net/netstat 计数器 netstat -st
TCPListenOverflows 全连接队列,没处理accept。
#netstat -nr 看路由表 route -n
#ss -antp -m -i
listen状态下 send-q表示backlog的长度。
#ifconfig, txqueuelen 发送队列的包数量
#sar -n DEV 1
#查看有些路由表 vim /etc/iproute2/rt_tables
# ip rule show table all 查看所有路由
# telnet
# nmap
# tcpdump
traffic control 流量控制 入门:
#tc qdisc show 显示网卡的排队规则
# tc qd add dev ens33 root netem delay 200ms
socket option: socket ,bind, listen, accpet man 7 socket 两个进程监听同一个端口,so_reuseport(since linux 3.9)。