目录
一、面向连接
三次握手:
1、双方发送的数据包名称
2.双方连接状态:
问题:为什么tcp需要三次握手才能建立连接,两次不行吗?
3、包序管理(重要!!!)
序号与确认序号
通过抓包研究tcp的序号与确认序号
结论:纯ACK数据包不消耗序号
发送数据的时候,针对每一个字节都进行了编号
二、四次挥手
2.1 连接数据包名称 双方连接状态
面试题1:挖坑分析TIME_WAIT的在哪里
面试题2:主动断开连接方为什么需要等待2MSL的时候之后,状态才能从TIME_WAIT状态,变迁为CLOSED状态
面试题3:如果服务端存在大量的TIME_WAIT状态,如何快速的重启进程?
一、面向连接
三次握手:
我们先来回想一下,三次握手是什么时候发生的呢?
结论1:服务端处于监听状态,客户端调用connect函数,才会进入三次握手阶段
结论2:三次握手阶段,程序猿没有具体参与,是由客户端和服务端的TCP协议进行连接的
1、双方发送的数据包名称
我们可以通过抓包来验证下三次握手的数据包名称:
2.双方连接状态:
问题:为什么tcp需要三次握手才能建立连接,两次不行吗?
1. 通过状态去解释
思路:2次握手,客户端认为连接已经建立,服务端认为连接还没有建立
2. 为什么服务端认为连接没有建立?
因为,没有第三次的ACK,服务端是没有办法确认,SYN+ACK数据包是否到达了客户端
3、包序管理(重要!!!)
先来复习一下TCP_socket的内容
服务端和客户端通过网络进行发送数据:
结论:
tcp维护了发送缓冲区和接收缓冲区,send函数发送的内容, 会先放到tcp的发送缓冲区当中,tcp自己择机发送 (tcp自己选择发送的时机, 自己选择发送的数据量)。 rev函数接收的内容, 是从tp的接收缓冲区当中进行接收的, 接收的数量由
程序员调用的recv函数的第三次参数决定。
那么这个东西和包序管理有什么关系呢?
在上面的图中,不论是服务端给客户端发送数据还是客户端给服务端发送数据,都需要保证两个东西:
可靠: 一定要能 可靠到达对方
有序: 针对于应用层而言的,发送方发送的数据是有顺序的,接收方接收数据的时候也是有顺序的。
结论:TCP要保证可靠和有序,TCP的发送方在发送数据的时候,针对发送的数据,进行了序号的编号
序号与确认序号
那么服务端给客户端发送数据的时候有没有序号的编号呢?
肯定是有的,有两套序号
通过抓包研究tcp的序号与确认序号
序号:发送方发送数据的时候,针对数据的编号
确认序号:接收方告诉发送方,期望下一次发送方从哪个序号开始发送数据,引申含义就是:接收方告诉发送发,确认序号之前的内容都收到了
我们可以直接把之前的HTTP的数据包拿来分析,只分析里面的TCP的部分
追踪一下就能得到:
我们来分析一下这个过程:
面试问题:
双方在连接建立的过程,序号一定要从0开始吗?
不一定,只要满足后续发送的数据,按照之前的序号进行编号就行了
结论:纯ACK数据包不消耗序号
我们现在用之前写的tcp_demo更好的理解一下这个:
我们利用抓包分析一下这个过程
上面过程画成图的话就是:
发送数据的时候,针对每一个字节都进行了编号
ack = 发送方发送数据的起始序号 + 发送方发送的数据长度
二、四次挥手
2.1 连接数据包名称 双方连接状态
强调:在连接建立的情况下,双方都可以发起断开连接的动作
面试题1:挖坑分析TIME_WAIT的在哪里
客户端先告诉服务端连接断开,这个时候服务端存在大量的TIME_WAIT状态怎么办呢?
1、 客户端由于是先给服务端发送的断开连接请求,所以TIME_WAIT状态不会存在服务端,而是客户端
2、面试官你是想问客户端存在大量的TIME_WAIT状态吗?----》最终问题可能归结为服务端先断开,存在大量TIME_WAIT状态怎么解决?
面试题2:主动断开连接方为什么需要等待2MSL的时候之后,状态才能从TIME_WAIT状态,变迁为CLOSED状态
面试题3:如果服务端存在大量的TIME_WAIT状态,如何快速的重启进程?
设置端口重用, setsockopt函数,就能解决这个问题。