tcp
# 从一个HTTP请求来看网络分层原理
一个HTTP超具体的请求的分层解析流程: 域名从浏览器解析域名获得ip, host解析域名获得ip, DNS 请求报文 -> 传输层 UDP (添加UDP报文) -> ARP (加上IP报文) -> 以太网(加上自己的MAC地址,加上下个地址的MAC) -> 物理层 () ====> 发到 路由器(3层协议) 【物理层->数据链路层->网络层】 -> xxxx的递归循环 -> DNS响应报文 原路返回 -> 这里就获得IP了
http (封装http的消息头) -> TCP五层模型 -> 服务器 -> 响应返回 (同上)
#HTTP协议 超文本传输协议(HyperText Transfer Protocol,HTTP) 传输 交给TCP
可扩展的语义 -> 消息头扩展 自描述消息格式 -> mp3,mp3,json.... 基于网络的超文本信息系统灵活的互动 -> html 动画
请求行报文格式 === 起始行
HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候, 一般会带上Referer,告诉服务器该网页是从哪个页面链接过来的, 服务器因此可以获得一些信息用于处理。 防盗链的使用
Server : nginx , Apache Date 在请求头和响应头都有。
3.HTTP请求的完整过程
tcp3次,组装http报文,
浏览器收到响应之后, 根据不同的格式做不同的事。 如果是下载的话就会下载。 如果是html的话, 就会开始渲染页面,再去请求html里面的内容.递归.
# TCP
双向全双工,客户端和服务端都可以关闭。
tcp 加上协议头,5元组。 报文标识,ACK、SYN、FIN等等。 Receive window 可接受。
源端口一般随机生成。
linux抓包: tcpdump -i 网卡name
windows,发送报文 nc
内核,一个监听端口,维护一个SYN队列。 收到ACK才出队。
查看tcp连接 netstat -tpn -c 1
连接关闭变成TIME_WAIT
第一次挥手,FIN 1 客户端不可写。
TIME_WAIT还要为什么等待2MSL(一个报文来回时间)? MSL 最大报文生成时间 防止滞留在网络中的报文,对新建立的连接造成数据扰乱,比如服务器中其他的报文还没发完,
MSS 是最大的,实际不超过他,会变动。 TCP不限制数据大小。
TCP 报文里面有seqNum 保证有序,去重,要保证完整性。
滑动窗口大小同通过 tcp三次握手和对端协商,且受网络状况影响 == 滑动窗口大小 和 tcp三次握手、网络状况、B端决定。
新的算法,选择性ack等等.. 有好多升级版的算法。
# https
验证证书是为了防止DNS解析被篡改成其他非法的服务器,具体验证是层层验证CA机构,一直到根机构(由操作系统或浏览器提供)都确认无误。
(接头身份,层层确认。)
下面就只要安心的保证,内容是加密且双方仅有2人知道。
具体是,非对称算法,最高机密级别保证密钥是不被人知道的。 (谍战密码本.)
再通过这个不被人知道的密钥,进行简单高效的对称加密。 (通过密码本交流.)
https://blog.csdn.net/weixin_30785593/article/details/96220957
https://blog.csdn.net/latico/article/details/102800197
#
bitMap原理?? 一次性创建一个大的数组吗??? 为什么不推荐用UUID为主键??? 排序吗?? 市面上的服务注册和发现有哪些?? 最重要的是什么?? 什么是一致性?? 怎么保证一致性?? 什么是熔断,用途?? redis 集群下如何保证原子性?? CAS是什么?? Spring怎么保证事务?
#
- 总结,项目的总结。或者说一下亮点, IM消息的重复,有序性,不丢失。
- 基础解题的思路得有。
- 要说项目的亮点。
- 不要说流水账,要简洁,说重点,不要带我觉得等等自我否定的语气。
# 商业工厂级别的强有序性的保证实现,参考TCP:
通知发送端方式2种,发消息时接口的返回,推送。
客户端有序列号 和 下个序列号 来保证强顺序性 ,和标识保证系统和消息状况。
但出现网络或者系统压力问题,客户端会触发,滑动时间窗口。 这个方案前端不接受。 那就后端实现,通知发送端,消息发送慢一点,或者发送阻塞消息。
那就后端实现,服务端要确保收到客户端的ack后,才发送下一条消息。 如果这里在服务端没有找到下一条消息,通知发送端,去做丢失消息的重发。
IM系统里面还有报警,通知。
https://blog.csdn.net/aa1928992772/article/details/85240358
# TCP分层
回来的时候会逐级去掉mac,ip,tcp报文头。
# 工具
# telnet
telnet 的⼀个最⼤作⽤就是检查⼀个端⼝是否处于打开,使⽤的命令是 telnet [domainname or ip] [port],这条命令能告诉我们到远端 server 指定端⼝的⽹连接是否可达。
可以用于发送请求
# netstat
- -a (all)显示所有选项,默认不显示LISTEN相关
- -t (tcp)仅显示tcp相关选项
- -u (udp)仅显示udp相关选项
- -n 拒绝显示别名,能显示数字的全部转化成数字。
- -l 仅列出有在 Listen (监听) 的服務状态
- -p 显示建⽴相关链接的程序名
- -r 显示路由信息,路由表
- -e 显示扩展信息,例如uid等
- -s 按各个协议进⾏统计
- -c 每隔⼀个固定时间,执⾏该netstat命令
# tcpdump
⼀个命令⾏的⽹络流量分析⼯具,功能⾮常强⼤,⼀般我们⽤来抓TCP的包。
tcpdump -i any
tcpdump -i any host 127.0.0.1
2
3
# wireshark
tcpdump,它是命令⾏程序,对 linux 服务器⽐较友好,简单快速适合简单的⽂本协议的分析和处理。
wireshark 有图形化的界⾯,在windows中使用,分析功能⾮常强⼤,不仅仅是⼀个抓包⼯具,且⽀持众多的协议。
wireshark可以演示下⽹络分层
# 思考
# TCP 为什么不会2次握手
比如最后一次,客户端没有最后的ACK,那么只能保证服务端,客户端是保证不了连接上的。 那么这样子就会导致服务端存在好多无效的连接,资源就浪费了。
如果是第二次,那么客户端就是一厢情愿了,可能对应的服务端都不存在。
# 四次挥手后为什么还要等待 2MSL后释放连接
- 防止客户端的最后一次的ACK报文丢失,导致B重复发送FIN。
- 防止滞留在网络中的报文(这些报文服务端是已经处理的了),对新建立的连接造成数据扰乱
# TCP的四次挥手为什么是四次?为什么不能是三次?
把最后一次去掉就是上面等待 2MSL的原因了,客户端不需要ACK确认,可能B发的FN丢失,客户端就一直等着连接。
把第2次去掉,第2/3合成一次,第2次是立刻发ack,进入close_wait状态,处理一些服务端存在的数据,这时间可以很长。
那么以LAST_ACK时刻发送的话,客户端可能已经等了几分钟了,这时客户端就会重发。
- 如果把第3次去掉,那么还在服务端的还未发送的数据就丢失了。
# TCP 为什么不会4次握手和5次挥手
3次握手就能保证双方建立连接了,再多一次,就浪费了。
挥手同理。
# 为什么 SYNFIN 不包含数据却要消耗一个序列号
凡是需要对端确认的,⼀定消耗TCP报⽂的序列号。
序列号,用来保证去重、有序。
SYN 和FIN需要对端的确认,所以需要消耗⼀个序列号。
# 什么是半连接队列?什么是SYN Flood攻击(半开放攻击)?
# TCP快速打开(TFO)的原理
TCP 快速打开(TCP Fast Open,TFO)
TFO 是在原来 TCP 协议上的扩展协议,它的主要原理就在发送第⼀个 SYN 包的时候就开始传数据了, 不过它要求当前客户端之前已经完成过「正常」的三次握⼿。
快速打开分两个阶段:请求 Fast Open Cookie 和 真正开始 TCP Fast Open
# Fast Open Cookie
发送SYN带cookie请求,服务端给ACK+cookie,客户端存cookie,发ACK
# TCP Fast Open
第一次发送SYN+Cookie+数据(http内容...),服务端校验cookie成功了,就返回SYN+ACK,校验失败就走正常的3次握手。
# 优势
- 利⽤握⼿去除⼀个往返 RTT ,有了cookie以后就SYN+数据一起发了,不需要再握手了。
- 可以防⽌ SYN-Flood 攻击之类的
# TCP报文中的时间戳有什么作用?
时间戳放到选型上面,由四部分构成:
类别(kind)、⻓度(Length)、发送⽅时间戳(TS value)、回显时间戳(TS Echo Reply)
- 计算往返时延 RTT(Round-Trip Time)
- 防⽌序列号的回绕问题
# TCP 的超时重传时间(RTO)是如何计算的?
最简单的想法就是取平均值。
经典算法引⼊了「平滑往返时间」(Smoothed round trip time,SRTT):经过平滑后的RTT的值,每测量⼀次 RTT 就对 SRTT 作⼀次更新计算。
平滑因⼦ α = 0.8
SRTT = 80% 的原始值 + 20% 的新采样RTT值
# TCP 的流量控制?
流量控制就是: 通过接收缓存区的⼤⼩,控制发送端的发送。如果对⽅的接收缓存区满 了,就不能再继续发送了,而是存在发送缓存区。
也就是再服务端发送的ACK中,会带有一个窗口大小。客户端利用滑动时间窗口算法,来控制发送速度。
# TCP 的keep-alive的原理
- 背景: 假设应⽤程序是⼀个 web 服务器,客户端发出三次握⼿以后故障宕机或被踢掉⽹线,对于 web 服务器 ⽽已,下⼀个数据包将永远⽆法到来,但是它⼀⽆所知。
- 需求 :考虑到了这种检测⻓时间死连接的需求,于是乎设计了 keepalive 机制。
- 它的作⽤ : 就是探测对端的连接有没有失效
- 实现: 通过定时发送探测包来探测连接的对端是否存活,不过默认 情况下需要 7200s 没有数据包交互才会发送 keepalive 探测包。
- 不足: 往往这个时间太久了,我们熟知的很多组件都没有开启 keepalive 特性,⽽是选择在应⽤层做⼼跳机制。
# TCP中的端⼝号
端⼝号在⽹络分层中TCP的消息头中,分为源端口和目标端口.
- 系统端口(熟知端⼝号): 范围0~1023
- 应用端口(已登记的端⼝号):范围1024~49151
- 源端口(临时端⼝号):范围49152~65535
#
# 确认号问题
A B 两个主机之间建⽴了⼀个 TCP 连接,A 主机发给 B 主机两个 TCP 报⽂,⼤⼩分别是 500 和 300, 第⼀个报⽂的序列号是 200,那么 B 主机接收两个报⽂后,返回的确认号是多少?
一个连接是seq+1
二个是: 2个报文累计 + 第一个序列号 = 500 + 300 + 200
# IP 数据包解析问题
收到 IP 数据包解析以后,它怎么知道这个分组应该投递到上层的哪⼀个协议(UDP 或 TCP)?
再IP头信息中,有个协议,该内容为。
协议: 区分IP协议上的上层协议。在Linux系统的/etc/protocols⽂件中定义了所有上层协议对应 的协议字段,ICMP为1,TCP为6,UDP为17
# 粘包和拆包 (opens new window)
TCP 提供了⼀种字节流服务,⽽收发双⽅都不保持记录的边界,应⽤程序应该如何提供他们⾃⼰的记录 标识呢?
应⽤程序使⽤⾃⼰约定的规则来表示消息的边界,⽐如有⼀些使⽤回⻋+换⾏("\r\n"),⽐如 Redis 的通信协议(RESP protocol)
- 消息定长,例如每个报文固定200字节,如果不够,空位补空格
- 在包尾增加回车换行符进行分割,如FTP协议
- 将消息分为消息头和消息体,消息头中包含消息的长度,字段等信息
- 更复杂的应用层协议
# TCP 和 UDP 的区别
- TCP是⼀个⾯向连接的、可靠的、基于字节流的传输层协议。
- UDP是⼀个⾯向⽆连接的传输层协议
# ⾯向连接
⾯向连接。所谓的连接,指的是客户端和服务器的连接,在双⽅互相通信之前,TCP 需要三次握⼿建⽴ 连接,⽽ UDP 没有相应建⽴连接的过程。
# 可靠性
可靠性。TCP 花了⾮常多的功夫保证连接的可靠,这个可靠性体现在哪些⽅⾯呢?
- TCP有状态:TCP 会精准记录哪些数据发送了,哪些数据被对⽅接收了,哪些没有被接收到,⽽且保 证数据包按序到达,不允许半点差错
- TCP可控制:意识到丢包了或者⽹络环境不佳,TCP 会根据具体情况调整⾃⼰的⾏为,控制⾃⼰的发 送速度或者重发
# 设计QQ
登陆采⽤TCP协议和HTTP协议,你和好友之间发送消息,主要采⽤UDP协议,内⽹传⽂件采⽤ 了P2P技术。
过程:
- 登陆过程,客户端client 采⽤TCP协议向服务器server发送信息,HTTP协议下载信息。登陆之 后,会有⼀个TCP连接来保持在线状态。
- 和好友发消息,客户端client采⽤UDP协议,但是需要通过服务器转发。腾讯为了确保传输消息 的可靠,采⽤上层协议来保证可靠传输。如果消息发送失败,客户端会提示消息发送失败,并可 重新发送。
- 如果是在内⽹⾥⾯的两个客户端传⽂件,QQ采⽤的是P2P技术,不需要服务器中转。
# 参考资料
什么是SYN Flood攻击? (opens new window)
- 直接攻击IP地址不被欺骗的SYN Flood被称为直接攻击
- 欺骗性攻击
- 分布式攻击(DDoS)
解决方法:
- 增加积压队列
- 回收最早的半开TCP连接
- SYN cookie
syn_flood攻击原理是什么?如何防范syn_flood攻击? (opens new window)
买好的防火墙服务,cookie源认证,reset认证,设置ip的黑名单。
流量控制(会有客户端未接收数)、超时重传时间计算规则、剔除长久未连接的客户端。