故事作者:冯学卫

最近创作

看看TA的故事

网络协议详解03—TCP协议

已锁定

冯学卫

官方工程师

  • 帖子

    180
  • 精华

    42
  • 被关注

    219

论坛等级:侠圣

注册时间:2007-08-03

钻石 钻石 如何晋级?

网络协议详解03—TCP协议

969

18

2023-11-03 16:52:22

star star star star star

TCP协议简介

UDP是一种没有复杂控制,提供面向无连接通信服务的一种协议。换句话说,它将部分控制转移给应用程序去处理(例如TFTP),自己却只是提供作为传输层协议的最基本功能。

TCP与UDP不同,TCP则“人如其名”,可以说对“传输、发送、通信”进行“控制”的“协议”。

TCP与UDP区别相当大。它充分地实现了数据传输时各种控制功能,可以进行丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。而这些在UDP中都没有。此外,TCP作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费。

TCP vs UDP

TCP提供面向有连接的通信传输。面向有连接是指在数据通信开始之前先做好通信两端之间的准备工作。

UDP是一种面向无连接的通信协议,因此不检查对端是否可以通信,直接将UDP包发送出去。TCP与此相反,它会在数据通信之前,通过TCP首部发送一个SYN包作为建立连接的请求等待确认应答。如果对端发来确认应答,则认为可以进行数据通信。如果对端的确认应答未能到达,就不会进行数据通信。此外,在通信结束时会进行断开连接的处理(FIN包)。

可以使用TCP首部用于控制的字段来管理TCP连接,一个连接的建立与断开,正常过程至少要来回7个包才能完成。

源端口号(Source Port)  表示发送端端口号,字段长16位。

目标端口号(Destination Port) 表示接收端端口号,字段长度16位。

序列号(Sequence Number)   字段长度32位。序列号(有时也叫序号)是指发送数据的位置。每发送一次数据,就累加一次该数据字节数的大小。序列号不会从0或1开始,而是在建立连接时由计算机生成的随机数作为其初始值,通过SYN包传给接收端主机。然后再将每转发过去的字节数累加到初始值上表示数据的位置。此外,在建立连接和断开连接时发送的SYN包和FIN包虽然并不携带数据,但也也会以一个字节增加对应的序列号。

确认应答号(Acknowledgement      Number)     确认应答号字段长度32位。是指下一次应该收到的数据的序列号。实际上,它是指已经收到 (确认应答号-1)为止的数据。发送端收到这个确认应答以后可以认为在这个序号以前的数据已经被正常接收。

数据偏移(Data      Offset)[TCP首部长度]    该字段表示TCP所传输的数据部分应该从TCP包的哪个位开始计算,当然也可以把它看作TCP首部的长度。该字段长4位,单位为4字节(即32位)。不包括选项字段的话,TCP的首部为20字节长,因此数据偏移字段可以设置为5。反之,如果该字段的值为5,那说明从TCP包的最一开始到20字节为止都是TCP首部,余下的部分为TCP数据。

保留(Reserved)   该字段主要是为了以后扩展时使用,其长度为4位。一般设置为0,但即使收到包在该字段不为0(安全问题),此包也不会被丢弃。

控制位(Control      Flag)    字段长度8位,每一位从左到右分别为URG、ACK、PSH、RST、SYN、FIN。这些控制标志也叫做控制位。当它们对应位上的值为1时,具体含义如下图所示。

1、URG ( Urgent Flag )

     该位为1时,表示包中有需要紧急处理的数据。对于需要紧急处理的数据,会在后面的紧急指针中再进行解释。 

2、ACK ( Acknowledgement Flag )

     该位为1时,确认应答的字段变为有效。也就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0。 

3、PSH ( Push Flag )

     该位为1时,表示需要将收到的数据立刻传给上层应用协议。PSH为0时,则不需要立即传而是先进行缓存。 

4、RST ( Reset Flag )

     该位为1时,这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包。

5、SYN ( Synchronize Flag )

表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被相应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手。

6、FIN( FIN Flag )

该位为1时,表示今后不会再有数据发送,希望断开连接(单项传输断开)。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换FIN位置1的TCP段。每个主机又对对方的FIN包进行确认应答以后就可以断开连接。不过,主机收到FIN设置为1的TCP段以后,不需要马上回复一个FIN置位的段给对方,而是可以等缓冲区中的所有数据都已经成功发送而被自动删除之后再发(半闭连接)。

7、ECE (ECN-Echo)

8、CER (Congestion Window Reduced)

       TCP支持使用TCP头中的两个标记(Flag)来支持ECN。分别用于回传拥塞指示(即指示发送者应减少信息发送量)和确认接收到了拥塞指示回应。这两个标记位就是ECE和CWR位。

       在TCP连接上使用ECE是可选的。当ECE被使用时,必须在连接创建时通过SYN和SYN-ACK段中包含适当选项来协商。

当在一个TCP连接上协商ECE后,发送方指示连接上的TCP段携带IP分组传输流量,将支持ECE的传输用ECT码点标记。这是支持ECE的中间路由器可以标记具有ECE码点的IP分组而不是丢弃它们,以指示即将发生的阻塞。

       当接收到具有遇到阻塞码点时,TCP接收者使用TCP头中的ECE标记回传这个阻塞指示。当一个端点收到TCP带有ECE位的段时,它减少其拥塞窗口来代替丢包。然后,它设置段的CWR位来确认阻塞指示。

       节点保持传输设置有ECE位的TCP段,直到它接收到设置有CWR的段。

窗口大小(      Windows Size )      该字段长为16位。接收端用于通知发送端,从此TCP段首部的确认应答号所指位置开始能够接收数据大小(8位字节)。TCP不允许发送超过此处所示大小的数据。不过,如果窗口为0,则表示可以发送窗口探测,以了解最新的窗口大小。但这个数据必须是1个字节。

校验和(      Checksum )      TCP校验和覆盖TCP首部和TCP数据,而IP首部中的校验和只覆盖IP的首部,不覆盖IP数据报中的任何数据。

TCP的校验和是必需的,而UDP的校验和是可选的。

TCP和UDP一样在计算校验和的时候使用TCP伪首部,如上图。为了让其全长为16位的整数倍,需要在数据部分的最后填充0。首先将TCP校验和字段设置为0。然后以16位为单位进行1的补码和计算,再将它们总和的1的补码和放入校验和字段。

接收端在收到TCP数据段以后,从IP首部获取IP地址信息构造TCP伪首部,再进行校验和计算。

紧急指针(      Urgent Pointer )   该字段长为16位。只有在URG控制位为1时有效。该字段的数值表示本报文段中紧急数据的指针。正确来讲,从数据部分的首位到紧急指针所指示的位置为止为紧急数据。因此也可以说紧急指针指出了紧急数据的末尾在报文段中的位置。

选项(      Options )  选项字段用于提高TCP的传输性能。选项是根据数据偏移(首部长度)进行控制。所以其长度最大为40字节。另外,选项字段尽量调整其为32位的整数倍。具有代表性的选项如下表。

TCP连接的建立与终止

TCP是一个面向连接的协议。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。

这种两端间连接的建立与无连接协议如UDP不同。UDP向另一端发送数据报时,无需任何预先的握手。

TCP用三次握手(three-way handshake)过程创建一个连接。在连接创建过程中,很多参数要被初始化,例如序列号初始化以保证传输和连接的可靠性。

一对终端同时初始化一个它们之间的连接是可能的。但通常是由一端打开一个套接字(socket)然后监听来自另一方的连接,这就是通常所指的被动打开(passive      open)。服务器端被动打开以后,客户端就能开始创建主动打开(active      open)

客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三次握手的一部分。客户端把这个段的连接的序号设定为随机数A

服务器端接收到SYN后以K一个合法的SYN/ACK来应答。ACK的确认序号为A+1,SYN/ACK包本身由会产生一个随机的序号B

最后,客户端再发送一个ACK来应答服务器端发来的SYN/ACK。当服务器端接收到了ACK,就完成了三次握手,并进入了连接创建状态。此时包序号被设定为收到的确认号A+1,序号设置为B+1。

TCP连接的终止

> 现在的网络通信都是基于socket实现的,当客户端将自己的socket进行关闭时,内核协议栈会向服务器自动发送一个FIN置位的包,请求断开连接。我们称首先发起断开请求的一方称为主动断开方。

> 服务器端收到请客端的FIN断开请求后,内核协议栈会立即发送一个ACK包作为应答,表示已经收到客户端的请求

> 服务器运行一段时间后,关闭了自己的socket。这个时候内核协议栈会向客户端发送一个FIN置位的包,请求断开连接

> 客户端收到服务端发来的FIN断开请求后,会发送一个ACK做出应答,表示已经收到服务端的请求

Python代码实现Socket TCP Server

Python代码实现Socket TCP Client

Python代码 Client连接Server实验环境

Python代码 TCP Client连接TCP Server的测试步骤

Python代码实现 Scapy模拟TCP通信

Python TCP Client代码:

Python代码实现 Scapy模拟TCP通信完整过程实验环境

运行Python TCP Client代码的结果



网络协议详解03—TCP协议 已锁定
编辑推荐: 关闭

请填写推广理由:

本版热门话题

冯工聊工业网络

共有34条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

快扫描右侧二维码晒一晒吧!

再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!

top
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。