ivan-94 / notepad

Read & Write & Blog
https://github.com/carney520/notepad/issues
0 stars 0 forks source link

TCP/IP 笔记 #13

Open ivan-94 opened 6 years ago

ivan-94 commented 6 years ago

协议栈

image

上图表示的是理论的网络协议分层OSI(open systems interconnection)和实际使用的TCP/IP之间的映射。 顶上三层处理具体网络应用(如FTP, HTTP)的所有细节, 对通信的细节了解很少;底下四层对具体网络应用了解不多,负责处理所有通信细节:发送数据,等待确认,给无序到达的数据排序, 计算校验和等等。 通过分层的结构,划分职责,隔离复杂度。 顶上三层对应的是用户进程, 而底下四层则作为操作系统的一部分提供。

ivan-94 commented 6 years ago

数据封包

应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装(Encapsulation). 数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理

不同协议层对数据包有不同的称谓:

缓冲区大小和限制

default

TCP的输出过程:

qq20180409-211320 2x
ivan-94 commented 6 years ago

协议族

image

常见的因特网协议使用:

qq20180409-211607 2x

端口

端口号(port number)被TCP、UDP、SCTP这三种协议用来区分服务进程。也就是说发起一个传输层协议连接必须指定 host + port 才能指定一个服务进程。端口号为16位的整数

image

TCP和UDP可以复用同一个端口. 比如DNS就同时支持UDP和TCP请求

套接字对

标识每个端点的两个值(IP+port)通常称为一个套接字。而标记一个连接,则需要两个套接字,分别为本地套接字和远程套接字。

ivan-94 commented 6 years ago

UDP

UDP 是一个简单的传输层协议。 特点:

ivan-94 commented 6 years ago

TCP

特点:

缺点:用时间和空间来换取可靠性。适合发送大量数据或可靠连接的场景

连接建立

三次握手(three-way handshake)

image

  1. 服务端准备好接收外来连接。可以通过调用socket、bind和listen这三个函数来完成。这个称为被动打开(passive open)
  2. 客户端通过调用connect发起主动打开(active open)。这会触发客户端发送一个SYN分节。 告诉服务器客户端将在后面连接中发送的数据的初始序列号,以及其他TCP选项
  3. 服务器必须确认ACK客户端的SYN, 同时自己也发送一个SYN分节, 包含服务器将在同一个连接中发送的数据的初始序列号。 4.客户端必须确认服务器的SYN

TCP 选项

连接终止

image

  1. 某端首先调用 close,称为该端执行主动关闭(active close)。该端发送一个 FIN 分节,表示数据发送完毕。
  2. 接收到 FIN 的对端执行被动关闭(passive close). 接收到它之后,将作为一个 EOF 传递给接收端应用。
  3. 再接收端应用接收到 EOF 后,调用 close 关闭它的套接字。这刀子他的 TCP 也发送一个 FIN
  4. 接收这个最终 FIN 的原发送端 TCP,确认这个 FIN

半关闭: 在步骤 2,3 之间,“被动关闭一端”到“主动关闭一端”还是可以发送数据的, 这被称为半关闭。 通过 shutdown 方法进行操作

应用程序意外退出,或套接字文件描述符被关闭,也会导致 TCP 发出一个 FIN。

数据交换过程

image

注意上图,服务器对客户端请求的确认是伴随应答发送的,这个做法称谓捎带(piggybacking), 通常在服务器处理请求并产生应答的时间小于200ms时发生。如果长于这个时间,将先发送确认后再发送应答

TIME_WAIT 状态

执行主动关闭的那一端,将在这个状态上停留持续 2MSL 时间(MSL, maximum segment lifetime, 最长分节生命周期)。MSL 的建议值是 2 分钟,实际上根据不同的实现,这个值在 1-4 分钟之间。为什么需要这个状态停留 4 分钟?

  1. 可靠地实现 TCP 全双工连接的终止. 假设发送给服务端的最后的 ACK 丢失了。 这时候服务端会重新发送 FIN,如果客户端停留在这个状态,可以重新发送最后的 ACK。如果客户端没有处于这个状态,可能响应一个 RST,这个分节将被服务端解析为一个错误。
  2. 允许老的重复分节在网络中消逝。


“迷途的重复分组(lost duplicate)或漫游的重复分组(wandering duplicate)"

可以假设 MSL 是任何 IP 数据报能够在因特网中存活的最长时间,分组可能会在网络中迷失,比如路由异常了,在迷途期间,发送端 TCP 超时并重传改分组,而重传的分组却通过某条候选路径到达最终目的地。早先迷失的分组也会最终也被送到目的地。这个原来的分组称为迷途的重复分组(lost duplicate)或漫游的重复分组(wandering duplicate)。

在一个连接关闭之后, 过一段时间后再相同的IP和端口之间建立另一个连接。后一个连接称为前一个连接的化身(incarnation),因为他们IP地址和端口号相同,如果没有TIME_WAIT 状态, 新的连接可能接收到迷失的分组。通过TIME_WAIT状态,足以让这些迷失分组被丢弃。

TCP状态图

一个连接有11中状态: image