特点

面向连接:通讯双方交换数据前必须建立连接
可靠的:多种确保可靠性的机制

关键名词解释

字节流服务:8bits(1Byte)为最小单位构成的字节流
套接字地址:

  1. TCP 使用“连接”(而不仅仅是“端口”)作为最基本的抽象,同时将TCP连接的端点称为插口(socket),或套接字、套接口。
  2. 插口和端口、IP地址段关系是:
    1. TCP 发送进程以字节流的形式传递数据,而接收进程也把数据作为字节流来接收,类似于假想的管道
    2. UDP 发送进程的数据报文都是独立的,因此UDP不是面向流的协议。
    3. 缓存:数据流向的每一个方向上又有两种缓存,一个是发送缓存,另一个是接收缓存
    4. 在传输层向IP层发送数据时要以分组为单位,而不是按字节流来发送,TCP协议把若干字节构成一个分组,可以把这样的分组称为报文段(segment),这种报文段并不一定都一样长,可以几个字节,也可以是几千字节。
  3. 字节号:
    1. 以字节为单位,字节号的定义范围为:0~232-1,
    2. 编号机制:随机
    3. 举例:假如随机号正好是1057,而要发送6000个字节,那么字节编号范围是:1057~7056
  4. 序号:
    1. 以字节为基础,TCP给每一个报文段指派一个序号
    2. 每个报文段的序号就是在这个报文段中第一个字节数据的序号
    3. 举例:比如TCP要传输6000个字节的文件。第一个字节的编号是10001,如果数据用5个报文段来发送,前4个报文段各携带1000字节的数据,最后一个报文段携带2000字节的数据:

第一个字节号范围:10001~11000
第二个字节号范围:11001~12000
第三个字节号范围:12001~13000
第四个字节号范围:13001~14000
第五个字节号范围:14001~16000

TCP协议格式:

TCP_data_structure

通过Wireshark抓TCP的一个包示例如下:

Transmission Control Protocol, Src Port: 59336, Dst Port: 443, Seq: 0, Len: 0
    Source Port: 59336
    Destination Port: 443
    [Stream index: 8]
    [Conversation completeness: Incomplete, DATA (15)]
    [TCP Segment Len: 0]
    Sequence Number: 0    (relative sequence number)
    Sequence Number (raw): 2876040241
    [Next Sequence Number: 1    (relative sequence number)]
    Acknowledgment Number: 0
    Acknowledgment number (raw): 0
    1000 .... = Header Length: 32 bytes (8)
    Flags: 0x002 (SYN)
        000. .... .... = Reserved: Not set
        ...0 .... .... = Nonce: Not set
        .... 0... .... = Congestion Window Reduced (CWR): Not set
        .... .0.. .... = ECN-Echo: Not set
        .... ..0. .... = Urgent: Not set
        .... ...0 .... = Acknowledgment: Not set
        .... .... 0... = Push: Not set
        .... .... .0.. = Reset: Not set
        .... .... ..1. = Syn: Set
        .... .... ...0 = Fin: Not set
        [TCP Flags: ··········S·]
    Window: 64240
    [Calculated window size: 64240]
    Checksum: 0x6f7a [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0
    Options: (12 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), SACK permitted
        TCP Option - Maximum segment size: 1460 bytes
        TCP Option - No-Operation (NOP)
        TCP Option - Window scale: 8 (multiply by 256)
        TCP Option - No-Operation (NOP)
        TCP Option - No-Operation (NOP)
        TCP Option - SACK permitted
    [Timestamps]

具体含义如下:

  • 源端口:16bits,端口号范围0~216-1。计算机上的进程要和其他进程通信需要通过计算机端口,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口。
  • 目标端口:16bits,端口号范围0~216-1。计算机上的进程要和其他进程通信需要通过计算机端口,通过指定目标计算机开放的端口,就可以与目标计算机开放的端口通信。比如示例中的443。
  • Stream index:在Wireshark中抓包可以显示出index值,是对ip A port A和ip B port B的对应,加上src/dst转换的值。
  • 序号:seq序号,32bits(4bytes)。用来标识从TCP源端口向目的端口发送的字节流,发起方发送数据时对此进行标记。TCP连接中传送的数据流中的每一个字节都编上一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。
  • 确认号:ack序号,32bits。是期望收到对方的下一个报文段的数据的第一个字节的序号。只有ACK标志位为1时,确认序号字段才有效,ack=seq+1
  • 首部长度:4bits,它指出TCP首部共有多少个4字节,首部长度可以在20~60字节之间(20字节固定首部+40字节选项部分)。因此这个字段值可以在5(5*4=20)~15(15*4=60)之间。
  • 保留字段:6bits,保留为今后使用,但目前应置为0。
  • 标志位:6bits,URG、ACK、PSH、RSH、SYN、FIN,具体含义如下:
    1. URG:紧急指针位(URGent),当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。
    2. ACK:确认位(ACKnowledge),只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效。
    3. PSH:推送位(PuSH),接收TCP收到推送位比特置1的报文段,就尽快地交付给接收应用进程,而不再等到整个缓存都填满了后再向上交付。
    4. RST:重置位(ReSeT),当RST=1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。一般在三种情况下出现:拒绝连接请求、异常终止连接、终止空闲连接。
    5. SYN:同步位(SYNchronous),同步比特SYN置为1,就表示这是一个连接请求或连接接受报文。
    6. FIN:终止位(FINal),用来释放一个连接。当FIN=1时,表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。
    7. TCP支持使用TCP头中的三个标记(flag)来支持ECN。第一个标记是随机和(Nonce Sum,简称NS),用于防止TCP发送者的数据包标记被意外或恶意改动。另两位用于回传拥塞指示(即指示发送者应减少信息发送量)和确认接收到了拥塞指示回应。这即是ECN-Echo(ECE)和Congestion Window Reduced(CWR)位。在TCP连接上使用ECN是可选的;当ECN被使用时,它必须在连接建立时通过SYN和SYN-ACK段中包含适当选项来协商。当在一个TCP连接上协商ECN后,发送方指示连接上的TCP段携带IP分组传输流量,将支持ECN的传输用ECT码点标记。这使支持ECN的中间路由器可以标记具有CE码点的IP分组而不是丢弃它们,以指示即将发生的阻塞。当接收到具*遇到阻塞码点时,TCP接收者使用TCP头中的ECE标记回传这个阻塞指示。当一个端点收到TCP带有ECE位的段时,它减少其拥塞窗口来代替丢包。然后,它设置段的CWR位来确认阻塞指示。节点保持传输设置有ECE位的TCP段,直到它接收到设置有CWR的段。
  • 窗口大小:8bits,窗口字段用来控制对方发送的数据量,单位为字节。TCP连接的一段根据设置的缓存空间大小确定自己的接收窗口大小,然后通知对方以确定对方发送窗口的上限。在部分抓包工具中,会看到Window和Calculated window size不一样,这时候可以通过Window size scaling factor的值与Window的值相乘,得出Calculated window size。表示窗口具有伸缩特性,当前窗口比较小但可以变化。变化的系数是Window size scaling factor,最大是Calculated window size。比如:
Window: 944
[Calculated window size: 30208]
[Window size scaling factor: 32]
  • 校验和:16bits,检验和字段检验的范围包括首部和数据这两部分。在计算校验和时,要在TCP报文段的前面加上12字节的伪首部(IP地址)。
  • 紧急指针:16bits,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号。
  • 选项字段:长度可变。TCP只规定了一种选项,即最大报文段长度MSS(Maximum Segment Size)。MSS告诉对方TCP:我的缓存所能接收的报文段的数据字段的最大长度是MSS个字节。其最大长度可根据TCP首部长度进行推算。MSS是TCP报文段中数据字段的最大长度。数据字段加上TCP首部才等于整个TCP报文段。MSS=MTU-20(TCP headers)-20(IP headers),一般情况下MTU在以太网中默认是1500bytes,所以得出MSS=1460 bytes

参考:https://zh.m.wikipedia.org/zh-hans/%E6%98%BE%E5%BC%8F%E6%8B%A5%E5%A1%9E%E9%80%9A%E7%9F%A5