TCP/IP协议

什么是TCP/IP协议

  • TCP/IP协议(传输控制协议/互联网协议)不是简单的一个协议,而是一组特别的协议,包括:TCP,IP,UDP,ARP等,这些被称为子协议。在这些协议中,最重要、最著名的就是TCP和IP。因此,大部分网络管理员称整个协议族为“TCP/IP”。

  • TCP/IP的迅速流行要归功于它的低成本、可在不同的平台间进行通信的能力和它开放的特性。“开放”的意思是软件开发人员可以自由地使用和修改TCP/IP的核心协议。TCP/IP是Internet实际采用的标准。UNIX和Linux一直都使用TCP/IP,Windows网络操作系统也以TCP/IP作为默认的协议。

网络分层

  • 链路层
  • 网络层
  • 传输层
  • 应用层

snipaste_level

  1. 第一层:网络接口层:TCP/IP协议的最低一层,对实际的网络媒体的管理,包括操作系统中的设备驱动程序和计算机对应的网络接口
  2. 第二层:网络层:该层负责相同或不同网络中计算机之间的通信主要处理数据包和路由。数据包是网络传输的最小数据单位。通过某条传输路线将数据包传给对方。IP协议,ICMP协议,IGMP协议。在IP层中,ARP协议用于将IP地址转换成物理地址,ICMP协议用于报告差错和传送控制信息。IP协议在TCP/IP协议组中处于核心地位。
  3. 第三层:传输层:提供TCP(传输控制协议),UDP(用户数据报协议)两个协议,主要功能是数据格式化、数据确认和丢失重传等。
  4. 第四层:应用层:TCP/IP协议的应用层相当于OSI模型的会话层、表示层和应用层,FTP(文件传输协议),DNS(域名系统),HTTP协议,Telnet(网络远程访问协议)

本文主讲第三层的TCP传输控制协议

简述

TCP将包排序并进行错误检查,同时实现虚电路间的连接。TCP数据包中包括序号和确认,所以未按照顺序收到的包可以被排序,而损坏的包可以被重传。

TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换 TCP窗口大小信息。

tcp包结构

snipaste_tcpdata

以太网数据包(packet)的大小是固定的,最初是1518字节,后来增加到1522字节。其中, 1500 字节是负载(payload),22字节是头信息(head),即MTU(Maximum Transmission Unit)为1500

snipaste_MTUSize

所以TCP包的大小:MTU字节大小1500-IP头部信息20-TCP头长度20-TCP timestrap option12 = 1448Byte

snipaste_TCPDataPage

根据上面这张图,可得知:IP数据包在以太网数据包里面,TCP数据包在IP数据包里面

tcp的序号seq

TCP会话的每一端都包含一个32位(bit)的序列号,该序列号被用来跟踪该端发送的数据量。每一个包中都包含序列号,在接收端则通过确认号用来通知发送端数据成功接收

当某个主机开启一个TCP会话时,他的初始序列号是随机的,可能是0和4,294,967,295(二的32次方-1)之间的任意值———tcp/ip详解协议卷第18章18.2.3解释初始序列号随时间变化,每个连接有不同的初始序列号,每4ms加一


在 TCP 数据报中,有一个 序列号 (Sequence Number)。如果序列号被人猜出来,就会展现出 TCP 的脆弱性。

如果选择合适的序列号、IP地址以及端口号,那么任何人都能伪造出一个 TCP 报文段,从而 打断 TCP 的正常连接[RFC5961]。一种抵御上述行为的方法是使初始序列号(或者临时端口 号[RFC6056])变得相对难以被猜出,而另一种方法则是加密。

Linux 系统采用一个相对复杂的过程来选择它的初始序列号。它采用基于时钟的方案,并且针对每一个连接为时钟设置随机的偏移量。随机偏移量是在连接标识(由 2 个 IP 地址与 2 个端口号构成的 4 元组,即 4 元组)的基础上利用加密散列函数得到的。散列函数的输人每隔 5 分钟就会改变一次。在 32 位的初始序列号中,最高的 8 位是一个保密的序列号,而剩余的备位则由散列函数生成。上述方法所生成的序列号很难被猜出,但依然会随着时间而逐步增加。据报告显示, Windows 系统使用了一种基于 RC4[S94] 的类似方案。

数据包的分割

那么一次性发送大量数据,就必须分成多个包。比如,一个 100000字节大小的文件/MSS最大报文长度 = TCP报文段

tcp的确认号ack

  1. 发送数据: 服务器向客户端发送一个带有数据的数据包。该数据包中的序列号和确认号与建立连接的第三步的数据包的序列号和确认号相同

  2. 确认收到: 客户端收到该数据包,向服务器发送一个确认数据包。该数据包中,序列号是为上一个数据包中的确认号值

    这个确认号为服务器发送的上一个数据包中的序列号+该数据包中所带的数据的大小

    回复确认收到的ack = 收到了序列号 + 数据的大小(同时也表示下一次期望收到的序号)

  • 主机A接收主机b 假设编号为0-535的字节(意味着mss值为535byte),主机A会在发往主机B的报文段的确认号字段ack上填上536
  • 每一个包都可以得到seq和ack, 接收方就可以根据编号进行排序(按照什么顺序进行还原原始文件)或者丢弃。发送方根据ack判断接收方是否收到了指定包,判断是否需要重传

    ——————这样就保证了数据通信的完整性和可靠性,防止丢包

tcp头字段

seq 序号 32位标识数据段在已发送的数据流中的位置
ack 确认号,验证是否已被接收
SYN 为1表示这是连接请求或是连接接受请求,用于创建连接和使顺序号同步
ACK 为1表示确认号字段有效
FIN 为1表示发送方没有数据要传输了,要求释放连接。
PSH 指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满
RST 为1表示出现严重差错。可能需要重现创建TCP连接。还可以用于拒绝非法的报文段和拒绝连接请求

三次握手

  1. 客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三次握手的一部分。客户端把这段连接的序号设定为32位的随机数A
  2. 服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK的确认码应为A+1,SYN/ACK包本身又有一个随机产生的序号B
  3. 最后,客户端再发送一个ACK。此时包的Seq被设定为A+1,而ACK的确认码则为B+1(第二次握手,服务端返回的Next seq)。当服务端收到这个ACK的时候,就完成了三次握手,并进入了连接创建状态。
  4. 这里的+1是根据发送的length来决定的

snipaste_startConnect

这里需要注意, SYN=0 在抓包工具上来看,就是没设置的意思

第一次握手

发送方发送syn = 1, 和

TCP Options

  • Maximum segment size: 65475 – MSS : 最大片段大小
  • Window scale: 8 (multiply by 256) – WS: “ TCP窗口比例”选项是一个选项,用于增加“传输控制协议”中允许的接收窗口大小,使其超过其以前的最大值65535字节
  • window size value: 65535 –Win
  • SACK permitted
    • That’s the “Sack-Permitted” option from RFC 2018, “TCP Selective Acknowledgment Options”. It says that the two machines can use “selective acknowledgment”, meaning that, instead of just saying “I got all bytes up to this sequence number”, they can say “I got all the bytes in this range and all the bytes in this other range”, with the implication being that bytes in ranges not listed were not received, so that they can say that they got bytes before and after some ranges, but not the bytes in the middle of the range.

1600271255259

1600271300193

第二次握手

1600271441785

第三次握手

1600271468100

这里有点疑惑的是: 并没有设置 syn flags

通过三次握手之后,建立 HTTP连接通道

1600271749837

1600271665014

数据传输

服务端发送的seq和ack必须和第三次客户端回传的seq和ack保持一致

客户端确认收到:seq = 服务端的ack ack = 服务端的seq+该数据包中所带数据的大小(同时也表示下一次期望收到的序号)

服务器回应:seq = 客户端回传的ack ack = 客户端回传的seq+客户端回传的length

服务器开始在通道里传送数据

1600272018881

客户端接收 http 数据

1600272340194

1600272419339

接收http 200之后,需要传递给服务器

1600272907328

失败的情况

如果客户端并没有接收到想要的信息,会再发一次tcp 请求

如果服务端已经完成 tcp连接,进入下一步

关闭连接

服务端关闭请求

1600273605916

客户端回复tcp

1600273696962

在这个过程中连接的每一侧都独立地被终止。当一个端点要停止它这一侧的连接,就向对侧发送FIN,对侧回复ACK表示确认

首先发出FIN的一侧,如果给对侧的FIN响应了ACK,那么就会超时等待2*MSL时间,然后关闭连接

注意: 首先发出FIN的一侧,如果给对侧的FIN响应了ACK,那么就会超时等待2*MSL时间,然后关闭连接

snipaste_stopConnect

总述

snipaste_summanry

1600309272878

文章目录
  1. 1. 什么是TCP/IP协议
  2. 2. 网络分层
  3. 3. 本文主讲第三层的TCP传输控制协议
    1. 3.0.1. tcp的序号seq
      1. 3.0.1.1. 数据包的分割
    2. 3.0.2. tcp的确认号ack
  • 4. tcp头字段
  • 5. 三次握手
    1. 5.1. 第一次握手
    2. 5.2. 第二次握手
    3. 5.3. 第三次握手
    4. 5.4. 通过三次握手之后,建立 HTTP连接通道
  • 6. 数据传输
    1. 6.1. 服务器开始在通道里传送数据
    2. 6.2. 客户端接收 http 数据
    3. 6.3. 失败的情况
  • 7. 关闭连接
    1. 7.1. 服务端关闭请求
    2. 7.2. 客户端回复tcp
  • 8. 总述
  • |