详情见:https://www.yuque.com/zaygee/tvg571/imghbh
1.tcp的报头
校验和:
发送端填充,CRC校验(循环冗余校验码(CRC),简称循环码)接收校验不通过,则认为数据有问题,和UDP校验的是数据本身,TCP校验的包含TCP首部、TCP数据部分
紧急指针:
只有在URG为1时有效 ,该字段为1表示报文中的紧急数据的指针
选项:
用于提高TCP的传输性能,根据首部长度控制,其最大长度为40字节
2.6个标志位
URG:The urgent pointer,紧急标志指针,为1,表示某一位需要被优先处理
PSH:推标志,提示接收端应用程序立即从TCP缓冲区把数据读走
ACK:Acknowledgement Number,确认标志,确认号是否有效,一般置为1
RST:复位标志有效。当RST=1时,表明TCP连接中出现严重差错,必须释放连接,再重新建立连接
SYN:Synchronize Sequence Numbers,请求建立连接,并在其序列号的字段进行序列号的初始值设定。建立连接,设置为1
FIN:结束标志,FIN=1时,表明此报文段的发送端的数据已经发送完毕,并要求释放传输连接
3.三次握手
第一次握手:
建立连接,客户端向服务端发送请求数据包,标志位SYN置为1,ACK为0,发送顺序号seq=X(随机int), 并进入SYN_SENT状态, 等待服务器确认
第二次握手:
服务器收到请求,需要确认客户端的数据包,发送SYN+ACK, SYN=1,ACK =1,并含有服务端的初始序号 seq=Y(随机int),以及服务端对客户端初始序号的确认,ACK=seq(客户端)+1(X+1)
第三次握手:
客户端接收到服务端的确认,向服务器发送一序列号,确认号ACK=Y+1,此后客户端和服务端进入 ESTAB_LISHED状态,完成三次握手
4.四次挥手
第一次挥手:主动关闭方发送第一个包,其中FIN标志位为1,发送顺序号seq为X。
第二次挥手:被动关闭方收到FIN包后发送第二个包,其中发送顺序号seq为Z,接收顺序号ack为X+1。
第三次挥手:被动关闭方再发送第三个包,其中FIN标志位为1,发送顺序号seq为Y,接收顺序号ack为X。
第四次挥手:主动关闭方发送第四个包,其中发送顺序号为X,接收顺序号为Y。至此,完成四次挥手
5.常见问题
1.浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?
在 HTTP/1.0 中,一个服务器在发送完一个 HTTP 响应后,会断开 TCP 链接。但是这样每次请求都会重新建立和断开 TCP 连接,代价过大。所以虽然标准中没有设定,某些服务器对 Connection: keep-alive 的 Header 进行了支持,
持久连接:既然维持 TCP 连接好处这么多,HTTP/1.1 就把 Connection 头写进标准,并且默认开启持久连接,除非请求中写明 Connection: close,那么浏览器和服务器之间是会维持一段时间的 TCP 连接,不会一个请求结束就断掉
2.一个 TCP 连接可以对应几个 HTTP 请求?
如果维持链接,一个tcp连接可以对应多个http请求
3.一个 TCP 连接中 HTTP 请求发送可以一起发送么(比如一起发三个请求,再三个响应一起接收)?
在 HTTP/1.1 存在 Pipelining 技术可以完成这个多个请求同时发送,但是由于浏览器默认关闭,所以可以认为这是不可行的。在 HTTP2 中由于 Multiplexing 特点的存在,多个 HTTP 请求可以在同一个 TCP 连接中并行进行
4.为什么有的时候刷新页面不需要重新建立 SSL 连接?
tcp连接有的时候会被浏览器和服务器会维持一段时间,tcp不需要重新连接,自然不需要重新建立ssl连接
5.浏览器对同一 Host 建立 TCP 连接到数量有没有限制?
Chrome 最多允许对同一个 Host 建立六个 TCP 连接
6.收到的 HTML 如果包含几十个图片标签,这些图片是以什么方式、什么顺序、建立了多少连接、使用什么协议被下载下来的呢
如果图片都是HTTPS连接并且在同一个域名下,那么浏览器在ssl握手之后会和服务器商量能不能用https2,如果能用的话就使用Multiplexing 功能在这个连接进行多路传输
如果只能用http/1.1,那浏览器就会在一个host上建立多个TCP连接,连接数量的最大限制取决于浏览器的设置
7.为什么建立连接协议是三次握手,而关闭连接却是四次握手?
服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求时,可以把ACK和SYN放在一个报文里来发送,但是关闭连接时,当收到对方的FIN 报文通知时,仅仅表示对方没有数据发送给你了,不代表你的所有数据都发送对对方了,当你已经没有数据发送给对方了,再发送FIN报文给对方表示你同意关闭连接了
8.为什么TIME_WAIT状态还需要等2MSL才能返回到CLOSE状态?
一是为了保证a发送的最后一个ACK报文能够到达b,如果这个ACK报文丢失,会使处在LAST_ACK状态的b收不到对已发送的FIN和ACK报文段的确认,b会超时重传这个FIN和ACK报文段,而a就在这个2MSL时间内收到这个重传的ACK+FIN报文段,接着a重传一次确认
二是防止已失效的连接请求报文段出现在本连接中,a在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续时间内所产生的所有报文段都中网络中消失
ps:什么是2MSL?MSL即Maximum Segment Lifetime,也就是报文最大生存时间
9.为什么不能用两次握手进行连接?
把三次握手改成仅需要两次握手,有可能发生死锁,例如客户端给服务端发送一个连接请求分组,服务端收到了这个分组,并发送了确认应答分组,假如两次握手,服务端认为连接已经成功的建立了就可以开始发送数据,可是客户端服务端的应答在传输中被丢失的情况下,将无法得知服务端是否已准备好,甚至怀疑服务端是否已收到自己的连接请求,在此情况下,客户端认为连接未建立成功,将忽略服务端发来的任何数据,一心等待连接的确认,而服务端在发出的数据超时后,重复发送同样的数据,这样就形成了死锁
10.TCP协议和UDP协议的区别是什么?
TCP协议是有连接的,即在开始传输数据之前,TCP的客户端和服务端必须通过三次握手建立连接,会话结束后也要结束连接,而UDP是无连接的
TCP 协议保证了数据按序发送按序到达,提供超时重传,但UDP无法保证
TCP有流量控制和拥塞控制,UDP 没有,网络拥堵不会影响发送端的发送速率
TCP协议首部需20个字节,UDP首部字段只需8个字节
TCP是一对一的连接,UDP可一对多,多对多,多对一的通信
TCP 面向字节流的服务,UDP 面向报文的服务
参考原文:https://blog.csdn.net/qq_34827674/article/details/106627403
https://blog.csdn.net/weixin_44786530/article/details/89299896