1、TCP/IP: 传输控制协议/网际协议
它是互联网的核心技术,并不是某一个协议而且协议的一个集合T![ (1)源端口和目的端口:各占16bit,端口是传输层与应用层的服务端口。
以HTTP为例,从下往上走分 物理链路层(802.3,802.11,eth)-IP网络层 -传输层(TCP/UDP)-应用层( HTTPFTP TELNET TFTP)
TCP头20字节:
(1)源端口和目的端口:各占16bit,端口是传输层与应用层的服务端口。
(2)序号字段:seq序号(小写),占32bit。TCP连接中传送的数据流中的每个字节都编上一个序号。序号字段值指的是本报文段所发送的数据的第一个字节的序号。
(3)确认号:ack序号(小写),占32bit。 是期望收到对方的下一个报文段的数据的第一个字节的序号。只有ACK标志位为1时,确认号字段才有效,ACK=SEQ+1.
(4) 标志位(大写): 共六个,即URG、ACK、PSH、RST、SYN、FIN。
a、紧急比特URG:当URG=1时,表明紧急指针字段有效。它告诉系统 此报文段中有紧急数据, 应尽快传送。
b、确认比特ACK:只有当ACK=1时确认号字段才有效,等于零时无效。
c、推送比特PSH:接收TCP收到推送比特 置1的报文段,就尽快交付给接受应用进程,而不用等到整个缓存都填满了后再向上交付。
d、复位比特RST:当RST=1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接, 然后再重新连接。
e、同步比特SYN:SYN为1时,表示 这是一个连接请求或连接接受报文。
f、 终止比特FIN:用来释放一个连接。当FIN=1时,表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。
(5) 数据偏移:占4bit,它指出TCP 报文段的数据的起始处 距离TCP报文段的起始处有多远。
(6) 窗口字段:占16bit,窗口字段用来控制对方发送的数据量,单位 为字节。
(7)检验和:占16bit,检验和字段检验的范围 包括首部和数据两部分。在计算检验和 时,要在TCP报文段的前面加上12字节的伪首部。
(8)紧急指针字段:占16bit,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号。
(9)选项字段:长度可变,TCP只规定一种选项,即最大 报文段长度MSS(Maxinum Segment Size)。
(10)保留字段:占6bit,目前应置为0。
二、TCP建立连接时有三次握手,断开连接时候为四次分手
三次握手:
网络上很多的解释三次握手有很多解释错误的,这里我使用抓包工具,让大家看着报文来说明这个过程
先上图:
注:理解三次握手的过程首先要理解上文中TCP报文段头部格式的几个名词
文字过程:
第一次握手:
首先客户端和服务器都是出于关闭状态(CLOSE),客户端A首先发起连接给B服务器,A会将请求报文中的标志位(大写)SYN=1 ACK =0(ACK缺省0),随机生成一个序列号(小写)seq = x(通常在建立连接时候为0,如下图),服务端recv到报文识别SYN=1,得知这是一个TCP连接请求数据报文(需要在内核申请fd,开辟空间),序号seq=x,表示传输数据时的第一个数据字节的序号是x(TCP是有序传输);
客户端A进入:SYN_SENT状态
有兴趣的朋友可以使用我方法也试一试,过滤设置为:tcp.flag
第一行就是A----->B请求报文,通常第一个序列号seq=0,即X为0;
SYN 占1bit位 Set 为1
第二次握手:
服务器B端收到请求报文,回复收到确认包,SYN=1,ACK=1(表示这是一个TCP连接响应数据报文),ack=seq+1,seq=y(同时包含主机B的初始序列号seq(B)=y,以及主机B对主机A初始序列号的确认号ack(B)=seq(A)+1=x+1,表示我下一个要收到的报文是x+1)
服务端B进入SYN_RCVD状态;
第三次握手
主机A要收主机B的确认报文,检查ack是否为x+1,ACK是否为1,如果正确在给服务端发送一个序列号seq(A)=x+1和确认号为ack(A)=y+1的报文 (ack(A)=y+1 表示下一个报文需要收到这个序列号的包);
A和B都进入ESTABLISED状态
四次挥手:
四次挥手是可以两端任意发起的,因为TCP是全双工通信的,以客户端发起为例
第一次挥手
Client发送一个FIN = 1,序号seq=u,主动发起并停止再发送数据 ,关闭Client到Server的数据传送,等待B端的确认;
Client进入FIN_WAIT_1状态;
第二次挥手
B收到连接释放报文段后即发出确认报文段,(ACK=1,确认号ack=u+1,序号seq=v),B进入CLOSE-WAIT(关闭等待)状态,此时的TCP处于半关闭状态,A到B的连接释放,但是B到A还未释放;
第三次挥手
A收到B的确认后,进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段 FIN = 1 Seq=w, ACK=1 ack=u+1。
第四次挥手
A收到B的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),A进入TIME-WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,A才进入CLOSED状态。
总结四次挥手过程:
起初A和B处于ESTABLISHED状态——A发出连接释放报文段并处于FIN-WAIT-1状态——B发出确认报文段且进入CLOSE-WAIT状态——A收到确认后,进入FIN-WAIT-2状态,等待B的连接释放报文段——B没有要向A发出的数据,B发出连接释放报文段且进入LAST-ACK状态——A发出确认报文段且进入TIME-WAIT状态——B收到确认报文段后进入CLOSED状态——A经过等待计时器时间2MSL后,进入CLOSED状态。
【问题】为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。
TCP协议能够实现报文的拥塞控制和流量控制
下期总结