网络基础协议之TCP
TCP 协议的简单描述
- TCP 是可靠传输连接
- TCP 需要建立完整连接才可以传输数据,即三次握手。
- TCP 有安全的断开机制,即TCP 四次挥手。保证数据的完整性
- TCP 协议传输数据报头部大小默认20字节,比UDP所消耗的网络资源更多。
- TCP协议采用窗口技术和流控制
TCP数据报首部格式
源端口:
当前主机发送的端口
目的端口:
和对端建立连接对应的端口
序号:
该数据用来表示一个TCP 数据片段,用来保证数据流中的部分没有丢失。同时也表示当前端成功发送的数据位数
确认号:
当前接收方成功接收发送方已经发送的数据位数,SYN和FIN标志位都要占1位
首选长度:
和IP数据包头部一样,也有个Options字段,长度是不固定的,而为了要确认整个TCP封包大小,就需要这个标志来说明整个封包区段的起始位置。这个字段指出TCP报文段的数据起始处距离 TCP报文段的起始处有多远。“数据偏移”的单位不是字节而是32bit字(4字节为计算单位)。没有任何选项字段的TCP头部长度为20字节;最多可以有60字节的TCP头部。
保留位:
包括Reserved(3bit)、Nonce(1bit)、CWR(1bit)、ECN-Echo(1bit),共6bit。
标记:
用来表示所传输的TCP数据包类型,该字段中可用的标记包括 URG、ACK、PSH、RST、SYN、FIN
- URG:紧急标志。表示TCP 包的紧急指针有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据。
- ACK:确认标志。表示应答域有效,1表示应答域有效,0表示未生效。
- PSH:表示Push操作。所谓push操作就是指在数据包到达数据端以后,立即传送给应用程序,而不是在缓冲区排队。
- RST:该标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包。
- SYN:同步序列,用来建立连接。SYN标志位和ACK 标志位搭配使用,当连接请求的时候,SYN=1、ACK=0;当连接被响应的时候,SYN=1、ACK=1。这个标志的数据包经常被用来进行端口扫描。扫描着发送一个只有SYN的数据包,如果对方响应了一个数据包回来,就表明该主机存在该端口。
- FIN:结束标志,表示双方并无数据需要进行传输,此时发送FIN 标志位的TCP 数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。当一个FIN 标志的TCP 数据包发送到一台计算机的特定端口后,如果这台计算机响应了这个数据包,并反馈回来一个RST标志 数据包,则表明这台计算机上面没有打开这个端口,但是同时也表明这个主机是存活的。
窗口大小:
告诉对端当前可以接收的数据大小,而并非是当前可以发送的窗口大小。此部分内容参考:Wireshark 网络分析就这么简单
校验和:
当数据要由发送端送出前,会进行一个检验的动作,并将该动作的检验值标注在这个字段上; 而接收者收到这个封包之后,会再次的对封包进行验证,并且比对原发送的 Checksum 值是否相符,如果相符就接受,若不符就会假设该封包已经损毁,进而要求对方重新发送此封包!在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。
紧急指针:
如果设置了URG 位,这个域将被检查作为额外的指令,告诉CPU 从数据包的哪个位置开始读取数据。
选项:
长度可变。TCP首部可以有多达40字节的可选信息,用于把附加信息传递给终点,或用来对齐其它选项。
填充字段(Padding):
如同 IP 封包需要有固定的 32bits 表头一样, Options 由于字段为非固定, 所以也需要 Padding 字段来加以补齐才行。同样也是 32 bits 的整数。这是为了使整个首部长度是4字节的整数倍。
附加内容
附加知识MTU
Maximum Transmit Unit,最大传输单元,即物理接口(数据链路层)提供给其上层(通常是IP层)最大一次传输数据的大小;以普遍使用的以太网接口为例,缺省MTU=1500 Byte,这是以太网接口对IP层的约束,如果IP层有<=1500 byte 需要发送,只需要一个IP包就可以完成发送任务;如果IP层有> 1500 byte 数据需要发送,需要分片才能完成发送,这些分片有一个共同点,即IP Header ID相同。
附件参数MSS
TCP 协议提交给IP协议的最大分片大小,不包含TCP 头和TCP 选项,只包含TCP Payload ,MSS是TCP用来限制application层最大的发送字节数,是tcp能发送的分组的最大长度。MSS是系统默认的,就是系统TCP/IP栈所能允许的最大包。在建立连接时,这个值已经被确定了,这个值并不是客观的值,而是由tcp/ip的实现确定的。
附加知识win
如果A发送给B window size = 8192,意思是:B最多可以连续发送8192 byte 给A,在A ACK这8192 byte之前。那A的这个8192byte 怎么来的呢? 一般来说,8192byte就是A的接收缓区,A_Receive_Buffer= 8192,如果B不小心发送超过8192 byte,如果application没有及时取走,则超过8192 byte 数据可能会因为A_Receive_Buffer满而被丢弃,所以B会严格遵守A的 advertised window size,如果A通告的window = 0,则B一定不会发送数据。
标注
上述内容均参考外展参考链接、Wireshark 数据包分析实战详解、Wireshark 网络分析就这么简单
- http://www.cppblog.com/tx7do/archive/2011/05/04/145699.html
- https://blog.csdn.net/wang7dao/article/details/16805337
- https://blog.csdn.net/a19881029/article/details/38091243
- http://www.networksorcery.com/enp/protocol/tcp.htm
- https://blog.csdn.net/stpeace/article/details/74152332
- http://www.360doc.com/content/18/0825/00/11935121_780993314.shtml