TCP连接的端点
TCP连接的端点是套接字(socket)。
socket=(IP地址:端口号)
TCP的首部
如下图所示,TCP的首部最少有20个字节 ,后面还有4n个字节是可选的。
首部的主要包含:
- 源端口和目的端口 各占2个字节
- 序号 4字节 共2^32,到头后从0开始。表示本次发送的数据的第一个字节的编号。TCP传送的字节流对每一个字节编号。
- 确认号 占4字节 是期望收到的对方下一个报文段的第一个数据字节的序号
- 数据偏移 占4位 数据起始地址和报文起始地址的距离,实际指出首部长度
- 确认ACK 仅当ACK=1时确认号字段才有效。TCP协议规定,当连接建立后,ACK必须为1
- 同步SYN 在建立连接时使用 当SYN=1而ACK=0时,表明这是一个连接请求报文段。而对方接受时会回复SYN=1,ACK=1。因此SYN=1表示这是一个连接请求会连接接受报文段(第一和第二次握手)
- 终止 FIN 当FIN=1时,表明此报文段的发送方的数据已经发送完毕,并要求释放运输连接
- 窗口 占2字节 表示允许对方发送数据的最大字节数
- 检验和
- 紧急指针
TCP三次握手过程
三次握手涉及到TCP首部的,同步为SYN,确认位ACK,序号seq,请求号ack.
假设A是客户端,B是服务端。
首先,B处于监听状态,等待客户端的连接请求
第一次:
A向B发送SYN=1,ACK=0,选择一个初始序号seq=x
第二次:
B向A发送SYN=1,ACK=1,确认号ack=x+1 , 同样选择一个序号seq = y
第三次:
A向B发送ACK=1,seq = x+1, ack=y+1
B收到A的确认后,连接建立
为什么需要三次握手
第三次握手是为了防止失效的连接请求到底服务器,让服务器错误地打开连接,白白浪费资源。
假设客户端发送的第一次请求在网络中滞留,客户端得到不到相应后就会重新发送请求建立连接。假设第一次无效的连接,很久后又到达了服务器,假设只有两次握手,则这时服务的就会进入连接建立状态,而客户端却认为这次请求是无效的,服务的还傻傻地等等数据的到来,浪费了资源。如果有三次握手,客户端会忽略服务的第二次握手的请求,使得连接不会建立,避免了资源浪费。
TCP四次挥手
TCP的四次挥手主要涉及首部的FIN,ACK,序号,确认号
假设是客户端A首先向服务的B请求接受连接
第一次:A向B发送报文,首部FIN=1,序号seq=u。A进入FIN_WAIT_1状态
第二次:B收到A的请求,发送报文,首部seq=v,ack=u+1,ACK=1 。进入close_wait状态
第三次:B的数据发送完毕,发送报文,首部 ack=u+1,seq = w,ACK=1,FIN=1。进入LAST_ACK状态
第四次:A收到B的断开请求,发送报文 ,首部ack=w+1,seq=u+1,ACK=1。进入TIME_WAIT状态
B收到第四次握手信息后进入close状态
A发送第四次握手后,等等2MSL,进入CLOSE状态
为什么需要四次握手
因为客户端发送FIN连接请求释放连接后,服务器接受请求后进入CLOSE_WAIT状态,这个状态就是为了让服务段发送还没有发送完的数据,发送完成后再发送FIN信号。
TIME_WAIT
客户端收到服务的释放连接的请求后,不是立马进入CLOSE状态,而是还要再等待2MSL。理由是:
- 确保最后一个确认报文能够到达。如果没能到达,服务端就会会重发FIN请求释放连接。等待一段时间没有收到重发就说明服务的已经CLOSE了。如果有重发,则客户端再发送一次LAST ack信号
- 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文