概述
概述
网络层只把分组发送到目的主机,但是真正通信的并不是主机而是主机中的进程。传输层为相互通信的应用进程提供了的逻辑通信,传输层向高层用户屏蔽了下面网络层的核心细节,使应用程序看起来像是在两个传输层实体之间有一条端到端的逻辑通信信道。
传输层协议与应用层协议之间的关系
-
协议端口号(端口):虽然通信的终点是应用进程,但只要把报文交到目的主机的某个目的端口,剩下的工作就由TCP或UDP来完成
-
工作原理:
防火墙是基于网卡的,只打开必要的端口,不必要的端口不允许接收数据,不影响服务的运行和监听。
服务使用TCP或UDP的端口侦听客户端请求;
客户端使用IP地址定位服务器,使用目标端口,定位服务;
可以在服务器网卡上设置只开放必要的端口,实现服务器网络安全 -
两种端口区别:
- 硬件端口:不同硬件设备进行交互的接口
- 软件端口:应用层的各种协议进程与运输实体进行层间交互的一种地址,此处的端口都是指软件端口
-
端口的表示:用16位的端口号来标志一个端口;端口号只具有本地意义,只标志本计算机应用层中各进程和运输层交互时的层间接口
-
端口号的分类:
- 服务器端口号:
熟知端口号:0~1023,这些端口号被指派给TCP/IP最重要的以下应用程序,让所有用户都知道
登记端口号:1024~49151,为没有熟知端口号的应用程序使用 - 客户端端口号:49152~65535,仅在客户进程运行时才动态选择,因此又叫短暂端口号
- 服务器端口号:
-
常见的应用层协议使用的端口
http = TCP + 80
Https = TCP + 443
RDP = TCP + 3389
ftp = TCP + 21
共享文件夹 = TCP + 445
SMTP = TCP + 25
POP3 = TCP + 110
telnet = TCP + 23
SQL = TCP + 1433
DNS = UDP + 53
用户数据报协议 UDP(User Datagram Protocol)
一般用于域名解析
特点
- UDP是无连接的:发生数据之前无需建立连接,减少了开销和发送数据之前的时延
- UDP使用尽最大可能交付:不保证可靠交付,因此主机不需要维持复杂的连接状态表
- UDP是面向报文的:UDP对应用层交下来的报文不做处理,直接加上首部后就转发,若报文过长,IP层会进行分片,可能使IP层效率降低
- UDP没有拥塞控制:因此网络出现拥塞不会使源主机发送速率降低,对实时应用很重要
- UDP支持一对一、一对多、多对一和多对多的交互通信
- UDP的首部开销小:只有8字节,比TCP的20字节首部短
首部
- 伪首部:只在计算校验和时使用,不参与数据传输,内容为网络层的首部信息的一部分
- 源端口:源端口号;在需要对方回信时选用;不需要时用全0
- 目的端口:目的端口号;在终点交付报文时必须使用
- 长度:UDP用户数据报的长度,最小值是8(仅有首部)
- 校验和:检测UDP用户数据报在传输过程中是否有错。有就丢弃
计算UDP校验和:与IP首部检验相似,但UDP的检验和把首部和数据部分一起都检
传输控制协议 TCP(Transmission Control Protocol)
特点
- TCP是面向链接的运输层协议:在使用TCP协议之前,必须先建立连接
- 每一条TCP链接只能有两个端点,每一条TCP连接只能是点对点的
- TCP提供可靠交付的服务:保证数据无差错、不丢失、不重复、按序到达
- 有流量控制,拥塞控制
- TCP提供全双工通信:允许通信双方任何时候都能发送数据
- 面向字节流:
流指的是流入到进程或从进程流出的字节序列;
TCP把应用程序交下来的数据仅看作一串无结构的字节流,把字节流组织成大小不等的数据块
TCP如何实现可靠传输
- 理想传输条件:
传输信道不产生差错
不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据
可靠传输的工作原理
- 停止等待协议。
停止等待:每发送完一个分组就停止发送,等待对方确认,在收到确认后再发送下一个分组-
无差错情况:
-
出现差错:
A只要超过一段时间每收到确认,就默认发送的分组丢失而重传之前的分组,就是超时重传注意:
- A发送完一个分组后,必须暂时保留已发送分组的副本,只有在收到相应确认后才删除
- 分组和确认都需要编号,才能明确哪个分组收到确认,哪个没收到
- 一个报文段从发送再到接收到确认所经过的时间称为往返时间 RTT,加权平均往返时间 RTTs 计算如下:
其中,0 ≤ a < 1,RTTs 随着 a 的增加更容易受到 RTT 的影响。
超时时间 RTO 应该略大于 RTTs,
TCP 使用的超时时间计算如下:
其中 RTTd 为偏差的加权平均值。
新 的 R T T d = ( 1 − b ) ∗ ( 旧 的 R T T d ) + b ∗ ∣ R T T s − 新 的 R T T 样 本 ∣ 新的RTTd=(1-b)*(旧的RTTd)+b*|RTTs-新的RTT样本| 新的RTTd=(1−b)∗(旧的RTTd)+b∗∣RTTs−新的RTT样本∣ 其中b=0.25
-
确认丢失和确认迟到:
确认丢失:
确认迟到:
-
- 连续ARQ协议:
发送方维持发送窗口,位于发送窗口内的分组都可以连续发送出去,而不需要等待对方确认,这样信道利用率就提高了
工作原理:
ARQ规定,发送方每收到一个确认,就把发送窗口滑动一个分组位置,接收方采用累积确认方式,在收到几个分组后,对按序到达的最后一个分组发送确认
优点:容易实现,确认丢失也不必重传
缺点:不能向发送方反映出接收方已经正确收到的所有分组信息
首部
- 序号seq :用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。
- 确认号ack :期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。
- 数据偏移 :指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。占一个字节,单位为4个字节。
- 紧急URG:当URG=1时,表明紧急指针字段有效,告诉系统此报文中有紧急数据,应尽快传送,而不采用原来的按排队顺序来传送。
- 确认 ACK :当 ACK=1 时确认号字段有效,否则无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置 1。
- 推送PSH:当收到PSH=1的报文时,就尽快交付接收应用进程,而不再等到整个缓存都填满后再向上交付
- 复位RST:当RST=1时,表明TCP连接中出现严重差错,必须释放连接,然后重新建立连接
- 同步 SYN :在连接建立时用来同步序号。当 SYN=1,ACK=0 时表示这是一个连接请求报文段。若对方同意建立连接,则响应报文中 SYN=1,ACK=1,接下来的过程中SYN=0 。
- 终止 FIN :用来释放一个连接,当 FIN=1 时,表示此报文段的发送方的数据已发送完毕,并要求释放连接。
- 窗口 :窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。
TCP的连接:
- 套接字 socket:套接字=(IP地址:端口号) ,例如(192.168.1.1:80)
- 每一条TCP连接唯一被通信两个端点(两个套接字)所确定:
- TCP连接::={socket1,socket2} = {(IP1:port1),(IP2:port2)}
- TCP连接的端点不是进程,而是套接字
- 同一个IP地址可以由多个不同的TCP连接,而同一个端口也能出现在多个不同TCP连接中
TCP滑动窗口
-
窗口是缓存的一部分,用来暂时存放字节流。发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小。
-
发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。
-
接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而 {34, 35} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收。
TCP流量控制
流量控制是为了控制发送方发送速率,保证接收方来得及接收。
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
TCP 拥塞控制
如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。
TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。
发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量,注意拥塞窗口与发送方窗口的区别:拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。
为了便于讨论,做如下假设:
- 接收方有足够大的接收缓存,因此不会发生流量控制;
- 虽然 TCP 的窗口基于字节,但是这里设窗口的大小单位为报文段。
慢开始与拥塞避免
发送的最初执行慢开始,令 cwnd = 1,发送方只能发送 1 个报文段;当收到确认后,将 cwnd 加倍,因此之后发送方能够发送的报文段数量为:2、4、8 …
注意到慢开始每个轮次都将 cwnd 加倍,这样会让 cwnd 增长速度非常快,从而使得发送方发送的速度增长速度过快,网络拥塞的可能性也就更高。设置一个慢开始门限 ssthresh,当 cwnd >= ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。
如果出现了超时,则令 ssthresh = cwnd / 2,然后重新执行慢开始。
快重传与快恢复
在接收方,要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。
在发送方,如果收到三个重复确认,那么可以知道下一个报文段丢失,此时执行快重传,立即重传下一个报文段。例如收到三个 M2,则 M3 丢失,立即重传 M3。
在这种情况下,只是丢失个别报文段,而不是网络拥塞。因此执行快恢复,令 ssthresh = cwnd / 2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。
慢开始和快恢复的快慢指的是 cwnd 的设定值,而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1,而快恢复 cwnd 设定为 ssthresh。
三次握手
假设 A 为客户端,B 为服务器端。
确认方ack=发起方seq+1,两端配对,因为tcp连接信号数据只有一个字节
- 首先 B 处于 LISTEN(监听)状态,等待客户的连接请求。
- A 向 B 发送连接请求报文,SYN=1,ACK=0,选择一个初始的序号 x。
- B 收到连接请求报文,如果同意建立连接,则向 A 发送连接确认报文,SYN=1,ACK=1,确认号为 x+1,同时也选择一个初始的序号 y。
- A 收到 B 的连接确认报文后,还要向 B 发出确认,确认号为 y+1,序号为 x+1。
- B 收到 A 的确认后,连接建立。
三次握手的原因
第三次握手是为了防止失效的连接请求到达服务器,让服务器错误打开连接。
客户端发送的连接请求如果在网络中滞留,那么就会隔很长一段时间才能收到服务器端发回的连接确认。客户端等待一个超时重传时间之后,就会重新请求连接。但是这个滞留的连接请求最后还是会到达服务器,如果不进行三次握手,那么服务器就会打开两个连接。如果有第三次握手,客户端会忽略服务器之后发送的对滞留连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。
四次挥手
以下描述不讨论序号和确认号,因为序号和确认号的规则比较简单。并且不讨论 ACK,因为 ACK 在连接建立之后都为 1。
- A 发送连接释放报文,FIN=1。
- B 收到之后发出确认,此时 TCP 属于半关闭状态,B 能向 A 发送数据但是 A 不能向 B 发送数据。
- 当 B 不再需要连接时,发送连接释放报文,FIN=1。
- A 收到后发出确认,进入 TIME-WAIT 状态,等待 2 MSL(最大报文存活时间,1 MSL = 2min)后释放连接。
- B 收到 A 的确认后释放连接。
四次挥手的原因
客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。
TIME_WAIT
客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:
- 确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
- 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。