为什么要三次握手

三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。
第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常
第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常
第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常
所以三次握手就能确认双方收发功能都正常,缺一不可。

第 2 次握手传回了 ACK,为什么还要传回 SYN?

接收端传回发送端所发送的 ACK 是为了告诉客户端,我接收到的信息确实就是你所发送的信号了,这表明从客户端到服务端的通信是正常的。而回传 SYN 则是为了建立并确认从服务端到客户端的通信。”

SYN 同步序列编号(Synchronize Sequence Numbers) 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement)消息响应。这样在客户机和服务器之间才能建立起可靠的 TCP 连接,数据才可以在客户机和服务器之间传递。

为什么要四次挥手

原因一:
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

断开一个 TCP 连接则需要“四次挥手”:

  • 客户端-发送一个 FIN,用来关闭客户端到服务器的数据传送
  • 服务器-收到这个 FIN,它发回一 个 ACK,确认序号为收到的序号加 1 。和 SYN 一样,一个 FIN 将占用一个序号
  • 服务器-关闭与客户端的连接,发送一个 FIN 给客户端
  • 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加 1

什么是TCP网络分层

TCP网络分为4层
应用层,传输层,网络层,物理层
在应用层,根据http协议组装数据包
在传输层,增加tcp头,包含端口号,序列号
在网络层,增加ip头,包含Ip地址等
在网络接口层,增加以太网头部包含MAC地址等,并通过网络接口层的物理层进行传输

为什么SYN/FIN不包含数据却要消耗一个序列号?

凡是需要对端确认的处理,一定消耗TCP报文的序列号。
SYN和FIN都需要对端的确认,所以需要消耗一个序列号。

假设没有序列号,每次服务端接收到序列号都要进行处理,导致资源浪费。

什么是半连接队列?什么是SYN Flood攻击?

半连接队列
服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立连接,服务器会把此种状态下的请求连接放在一个队列里,我们把这种队列称之为半连接队列。
服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。
每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s,2s,4s,8s…
SYN FLood攻击
Client端大量伪造IP发送SYN(建立连接)包,服务端回复的ACK(响应)+SYN(建立连接)去到一个【未知】的IP地址,势必会造成大量的连接处于SYN_RCVD状态,而服务器的半连接队列大小也是有限制的,如果半连接队列大小也是有限的,如果半连接队列满,也会出现无法处理正常请求的情况
防范方法:
1.对SYN包进行监视
如果发现某个IP发起了较多的攻击报文,直接将这个IP列入黑名单即可。当然下述的方法也可以对其进行防范。
2.延缓TCB分配方法
从前面SYN Flood原理可以看到,消耗服务器资源主要是因为当SYN数据报文一到达,系统立即分配TCB,从而占用了资源。而SYN Flood由于很难建立起正常连接,因此,当正常连接建立起来后再分配TCB则可以有效地减轻服务器资源的消耗。
3.无效连接监视释放
这种方法不停监视系统的半开连接和不活动连接,当达到一定阈值时拆除这些连接,从而释放系统资源。这种方法对于所有的连接一视同仁,而且由于SYN Flood造成的半开连接数量很大,正常连接请求也被淹没在其中被这种方式误释放掉,因此这种方法属于入门级的SYN Flood方法。

说说TCP快速打开(TFO)的原理

TCP快速打开(TCP Fast Open,TFO)
TFO是在原来TCP协议上扩展协议,它的主要原理就在发送第一个SYN(建立连接)包的时候就开始传数据了,不过它要求当前客户端之前已经完成过[正常]的三次握手
快速打开分两个阶段:请求Fast Open Cookie和真正开始TCP Fast Open
第一个阶段Fast Open Cookie
第一次:Client端发送SYN包(在header捎带Cookie request)Server端收到后生成Cookie值,放在header里传送给发送端
第二次:Server端发送SYN包(在header里捎带生成Cookie值)和ACK(响应)Client收到后把Cookie存储在本地
第三次:Client端给Server端发送ACK(响应)确认
第二个阶段TCP Fast Open
Client端发送的数据包包括(数据(HTTP请求、SYN包、在header捎带Cookie))Server端收到消息后校验Cookie的合法性,合法则响应ACK确认,如果不合法则丢弃包走正常的建立连接流程

TCP Fast Open
一个最显著的优点是可以利用握手去除一个往返RTT
可以防止SYN-Flood攻击之类的

TCP报文中的时间戳有什么作用?

头部信息中存在时间戳(类别、长度、发送方时间戳、回显时间戳)
防止序列号的回绕问题
TCP的序列号用32bit来表示,因此在2^32字节的数据传输后序列号就会溢出回绕。TCP的窗口经过窗口缩放可以最高到1GB,在高速网络中,序列号在很短的时间内就会被重复使用。

TCP的超时重传时间是如何计算的?

TCP具有超时重传机制,即间隔一段时间没有等到数据包的回复时,重传这个数据包
这个重传间隔也叫做超时重传时间
RTO(重传时间)太小,导致不必要的重传;RTO太大,丢包很久才重传;
image.png
重传时间设置可以参考过往的RTT平均值与新采样的RTT的值做一个平滑,如果a过大,那么对新的网络波动不敏感,如果a过小,那么就会对新的网络波动过于敏感。

能不能说一说TCP的流量控制?

  一般来说,我们总希望数据传输的更快一些。但如果发送方把数据发得过快,接收方就可能来不及接收,这就会造成数据的丢失。流量控制(flow control)就是让发送方的发送速率不要太快,要让接收方来得及接收。
  利用滑动窗口机制可以很方便地在TCP连接上实现发送方流量控制。通过接收方的确认报文中的窗口字段,发送方能够准确地控制发送字节数。
通常来讲,都希望数据发送的越快越好,但是实际情况是,如果数据发送过快,接收端来不及接收,就会造成数据的丢失浪费。因此流量控制就是要让发送方不要发送太快,让接收方来得及接收。TCP使用滑动窗口机制对发送方实现流量控制。
发送方有发送缓冲区,接收方有接收缓冲区。滑动窗口会移动将发送缓冲区中的数据发送出去。接收方会将数据暂存到接收缓冲区并返回确认。发送方先将滑动窗口内的数据按照字节序号发送,再接收到数据确认之后,删除窗口中的数据,然后平移滑动窗口准备发送后边数据。数据丢失会有超时重传机制。接收方返回确认的时候会根据自己缓冲区中的容量返回给窗口的大小值,接收方再接收到确认的时候根据这个值调整自己的发送窗口大小。
如果窗口调整为0之后,会有什么情况?
如果窗口调整为0,说明接收方的接收缓存满了,过一段时间,当缓冲区有容量的时候,会发送给发送方调整窗口大小值的通告。
如果这个通告丢失了怎么办?
如果通告丢失,则会陷入死锁。发送方等待接收方的通告新的窗口值,接收方等待发送方发送新的数据,从而陷入相互等待,最终死锁。
如果陷入死锁怎么办?
TCP会设置一个0窗口计时器。一旦发送窗口为0,TCP则会启动这个计时器,一旦计时器超时。发送方就会向接收方发送一个0窗口探测报文段,接收方接收到这个报文段则向发送方返回自己的窗口值。如果此时窗口值仍未0,则重启超时计时器。如果不为0,则发送方可以继续发送数据,打破死锁局面。

https://zhuanlan.zhihu.com/p/409560860

如何理解TCP的keep_alive的原理?

一个TCP连接上,如果通信双方都不向对方发送消息,那TCP连接就不会有任何数据交换。
假设应用程序是一个web服务器,客户端发出三次握手以后故障宕机或踢掉网线,对于web服务器而言,下一个数据包将永远无法到来,但是它一无所知。
TCP协议的设计者考虑到了这种检测长时间死连接的需求,于是乎设计了keepalive的机制。
它的作用就是探测对端的连接有没有失效,通过定时发送探测包来探测连接的对端是否存活,不过默认情况下需要7200s没有数据包交互才会发送keepalive探测包,往往这个时间太久了,我们熟知的很多组建都没有开启keepalive特性,而是选择在应用层做心跳机制。

聊一聊TCP中的端口号?

端口号默认网络分层中的传输层
TCP用两个字节的整数来表示端口号,一台主机最大允许65536个端口号
熟知端口号(HTTP:80,HTTPS 4443,SSH 22);已登记的端口号(MySQL 3306,Redis 6379,MongoDB 27017);临时端口号

TCP拥塞

拥塞:在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种现象称为拥塞。
总资源需求 > 可用资源
拥塞控制:防止过多的数据注入到网络中,使网络中的路由器或链路不致过载。
拥塞控制与流量控制的区别:
流量控制往往指点对点通信量的控制,是个端到端的问题(接收端控制发送端)。流量控制所要做的是抑制发送端发送数据的速率,以便使接收端来得及接收。
拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素。
TCP拥塞控制是避免网络拥塞的算法,是互联网上主要的一个拥塞控制措施。它使用一套基于线增积减(线性增,乘性减)模式的多样化网络拥塞控制方法来控制拥塞。在互联网上应用中有相当多的具体实现算法。
TCP拥塞控制方法
TCP采用基于控制窗口的方法进行拥塞控制。
TCP发送方维持一个拥塞窗口cwnd(Congestion Window)。
拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送端利用拥塞窗口根据网络的拥塞情况调整发送的数据量。所以,发送窗口大小不仅仅取决于接收方公告的接收窗口,还取决于网络的拥塞情况,所以真正的发送窗口值为:Min(接收方窗口值,拥塞窗口值)

拥塞的判断

  • 超时
  • 冗余ack:由于中间个别报文在网络中丢失,导致后续报文在传输时收到重复ack。网络中可能存在拥塞。(改进后版本的策略,快重传模式)

image.png

拥塞的四个算法

  • 慢开始和拥塞避免

TCP连接初始化时,将拥塞窗口设置为1,慢开始门限ssthresh设置为16个报文段
当拥塞窗口cwnd< 慢开始门限ssthresh,发送端处于慢启动阶段,窗口指数性增长
当拥塞窗口cwnd> 慢开始门限ssthresh,发送端处于拥塞避免阶段,窗口线性增长
当超时事件发生时,慢开始门限设置为拥塞窗口的一半,拥塞窗口设置为1,ssthresh=cwnd/2,cwnd=1MSS,进入慢开始阶段。
当收到三个重复ack,慢开始门限设置为拥塞窗口的一半,拥塞窗口值减半,ssthresh=cwnd/2,cwnd=cwnd/2,执行拥塞避免算法。

  • 快重传

快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段。

  • 快恢复

(1)当发送方连续收到三个重复确认时,把慢开始门限设置为拥塞窗口的一半,拥塞窗口设置为原来的一半。ssthresh=cwnd/2,cwnd=cwnd/2
(2)由于发送方现在认为网络很可能没有发生拥塞(如果网络发生了严重拥塞,就不会一连有好几个报文段连续到达接收方,也就不会导致接收方连续发送重复确认)。因此与慢开始不同之处就是现在不执行慢开始算法(即拥塞窗口现在不设置为1)而是把拥塞窗口的值设置为原先窗口值得一半,然后开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大。

Cookie 的作用是什么? 和 Session 有什么区别?

Cookie原理:
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
cookie原理:
(1)浏览器端第一次发送请求到服务器端
(2)服务器端创建Cookie,该Cookie中包含用户的信息,然后将该Cookie发送到浏览器端
(3)浏览器再次访问服务器端时会携带服务器端创建的Cookie
(4)服务器端通过Cookie中携带的数据区分不同的用户
session原理:
(1)浏览器端第一次发送请求到服务器端,服务器端创建一个Session,同时会创建一个特殊的Cookie(name为JSESSIONID的固定值,value为session对象的ID),然后将该Cookie发送至浏览器端
(2)浏览器端发送第N(N>1)次请求到服务器端,浏览器端访问服务器端时就会携带该name为JSESSIONID的Cookie对象
(3)服务器端根据name为JSESSIONID的Cookie的value(sessionId),去查询Session对象,从而区分不同用户。
如果name为JSESSIONID的Cookie不存在(关闭或更换浏览器),返回第一步中重新去创建Session与特殊的Cookie。
如果name为JSESSIONID的Cookie存在,根据value中的SessionId去寻找session对象
如果value为SessionId不存在(Session对象默认存活30分钟),返回第一步重新去创建Session与特殊的Cookie
如果value为SessionId存在,返回session对象
cookie与session的区别:

  • cookie数据保存在客户端,session数据保存在服务端。
  • cookie不安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗。
  • session会在一定时间内保存在服务器上。当访问增多,会比较占用服务器,如果主要考虑到减轻服务器性能方面,应当使用cookie。

所以,将登陆信息等重要信息存放为session;其他信息如果需要保留,可以放在cookie中。

GET 和 POST 比较

HTTP状态码

HTTP1.0和HTTP1.1的区别

HTTP和HTTPS的区别

TCP特点

TCP和 UDP的区别

TCP粘包是怎么产生的

TCP可靠传输

什么是全双工通信、单工通信、半双工通信?

https://www.bilibili.com/video/BV1L4411a7RN?spm_id_from=333.337.search-card.all.click&vd_source=f70f40b5a7cb44526a8792084725fba2

参考

【计算机网络】学习笔记汇总(目录)(谢希仁)
https://zhuanlan.zhihu.com/p/404693092