TCP协议封装格式及三次握手四次断开

7 Jun

开发Web,免不了遇到客户打不开网页,网页显示不正确等问题。通常工程师会收到一段log或用Wireshark截一个pacp。了解了TCP协议,及TCP的连接断开机制,对解析问题帮助很大。

进入正题前先啰嗦几句(熟悉的可略过)

网络开发遵从OSI 7层协议,但其实TCPIP 5层协议才是事实模型。见下图:

20151125144952178

TCPIP 5层协议将上3层(应用层,表示层,会话层)糅合到了一起。还有TCIPIP 4层模型,还将下面2层(数据链路层,物理层)糅合到了一起

1.应用层(应用层,表示层,会话层):

用于表示数据,图像,加密压缩(ASCII,EBCDIC,JPEG),管理同步(操作系统,应用读取)。相关协议极其丰富:浏览网页HTTP,文件传输TFTP / FTP / NFS,邮件SMTP,远程登录Telnet,网络管理SNMP,名称管理DNS等

2.传输层:

用于可靠/不可靠方式传送数据。相关协议:TCP,UDP

3.网络层:

用于寻址。相关协议:IP,ICMP,ARP,RIP,EIGRP,OSPF等。

4.数据链路层:

用于数据传递给对方。相关协议:802.3/802.2,HDLC,FR,PPP,STP等。

5.物理层:

用于以物理介质传送数据。EIA/TIA-232 V.35/RJ45等。

(现在进入正题。下面是我个人对TCP封装字段的理解,权威的请查阅wikipedia或RFC793)

20151125145725947

1.源端口号(16位)和目标端口号(16位)

端口号。它俩和源IP和目标IP构成一个TCP连接。常用的TCP端口有:HTTP 80,FTP 21,SMTP 25,Telnet 23,DNS 53

2.序列号(32位)

如下载1G视频,服务器不可能直接发过来,肯定需要分批发过来,序列号就是分批段的序号。

3.确认号(32位)

上面序列号是分批发过来的序号,因此确认号就是期望收到的下一个序列号。比如确认号为5,表示序列号1-4的都收到了,现在需要序列号为5的段。确认号和后面的ACK标志位一起用,当ACK标志位1时确认号起作用。

4.首部长度(4位)

指明段头部长度。如没有最下面的可选项和数据,正常的长度是20 byte。最大长度是60 byte

5.保留(6位)

全0,留给将来用。(通常future means never,工程狮都懂的)

6.Flag(6位)

URG:为1表示下面的紧急指针(16位)有效

ACK:为1表示上面的确认号(32位)有效

PSH:为1表示将数据立即交给应用程序(默认收到的数据是暂时缓存到内存的)

RST:为1表示断开TCP连接

SYN:为1表示请求TCP连接(具体见下面TCP 3次握手连接)

FIN:为1表示数据发送完毕(具体见下面TCP 4次断开连接)

7.窗口大小(16位)

用于流控机制和阻塞避免机制。流控机制简单地说就是TCP有能力判断通信双方间网络的通畅程度,来降低网络中传送数据的速度。后者看名字就能知道是什么意思。

比如你家ADSL 10M带宽,去服务器上下载视频,服务器端出接口的带宽通常很大有几个G,此时按G给你传数据显然不合理,TCP的窗口大小就起作用了,指明了当前本地可接收数据的缓冲区大小。

8.校验和(16位)

用于防止上面的数据被篡改,自己先将上面的数据校验一遍保存到校验和发送出去。对方收到数据自己校验一遍后和校验和里数据对比,一致的话表示上面的数据未被篡改

9.紧急指针(16位)

当上面的URG为1时有效。指向包内数据段的某个字节,不进入缓冲直接交给上层进程(非紧急数据是要进入缓冲的)

10.可选项

只知道有个MSS(Maximum Segment Size)建立连接时向对方通知本机可以接收的最大TCP段长度。其余没全部研究过,可查阅RFC793。

11.数据

(顾名思义)

TCP是可靠的传输协议,因此建立连接时需要双方握手,采用3次握手机制:

20151125171215697

简单地说就是:SYN → SYN+ACK → ACK。下图为一个典型的TCP连接请求:

20151125174922004

断开连接时,采用4次断开机制:

20151125171926224

简单地说就是:FIN+ACK → ACK     FIN+ACK → ACK。下图为一个典型的TCP断开请求:

20151125175231861

Q:那为何建立连接是3次握手,断开连接要4次握手呢?断开连接同样3次握手可以吗?

A:其实3次断开在技术上完全可以做到,很容易可以将上图中接收方的步骤2或3去掉。采用4次握手断开的原因是,网络是双向的。

假设A和B在互相从对方主机上下载数据,A传送完数据后,就通知B要断开连接。此时如果采用3次握手断开机制,B立刻断开连接的话,B还有未传送完 的数据将无法继续传送。因此采用4次握手断开机制,A传送完数据后通知B要断开,B回复知道了,A收到后就不在向B传送数据。等B也传送完数据后通知A要 断开,A回复知道了,B收到后就不再像A传送数据。这样A和B直接的TCP连接才彻底断开。

Leave a Reply

Your email address will not be published. Required fields are marked *