传输层存在的基本理由:进程到进程的传递。
(网络层不对数据报分组进行排序)
传输层的协议的类型
{
U
D
P
:简单的协议
T
C
P
:复杂的传输层协议
S
C
T
P
:为多媒体这样的多接口与多流应用而设计
传输层的协议的类型
需求:
实际的通信发生在两个进程之间,我们需要进程到进程的传递。
但是任何时刻,源主机上运行着多个进程,并在目的主机上也运行着多个进程。需要某种机制,将源主机上的某个进程的数据传输到目的主机上的对应进程上。
实现进程到进程间通信的方式:两个进程以客户client/server的方式进行通信。
客户机client:本地主机上的进程称为client,通常需要来自远程主机上的进程提供的服务。
服务器server:远程的主机称为服务器。
这两个进程(客户机和服务器)有着相同的名字。
e.g. 客户机从远程机器上获取日期和时间,需要在本地主机上运行Daytime客户进程和远程机器上运行Daytime服务进程。
目前OS支持多用户和多程序运行的环境。一个远程计算机在同一时间可以运行多个服务器程序。
我们必须定义:
需要传送消息到多个目的地之一的某个特定目的地时,需要一个地址。
如果不是点到点连接(点到多点),那么需要一个MAC地址从多个节点中选择一个节点。数据链路层的帧需要:
网络层,需要一个IP地址来选择百万主机中的一个主机。
端口号 port number:传输层地址,利用这一地址从目的主机上运行的多个进程中选择相应的进程。
端口号为0~65535之间的16位整数
客户机的端口号(ephemeral port number):自己定义的,运行在客户机上的传输层软件随机选择,这是临时端口号(ephemeral port number )。
服务器的端口号(well-known port number):这个端口号不能随机选择。如果随机选择,那么访问这个服务器时将不知道端口号。使用全局端口号——熟知端口号(well-known port number)。
当然,有时,一些客户端也被分配了熟知端口号。
端口号地址被IANA划分成三种范围:
端口号地址的范围
{
W
e
l
l
−
k
n
o
w
n
p
o
r
t
s
{
范围:
0
−
−
1023
性质:由
I
A
N
A
分配
R
e
g
i
s
t
e
r
e
d
p
o
r
t
s
:
{
范围:
1024
−
−
49152
性质:
I
A
N
A
不分配也不控制,可以在
I
A
N
A
注册防止重复
D
y
n
a
m
i
c
p
o
r
t
s
{
范围:
49152
−
−
65535
性质:不受控制也不需要注册,可以由任何进程使用
端口号地址的范围

进程到进程传递需要两个标识符:IP地址和端口号。
套接字地址Socket Address:IP地址和端口号的结合。
{
客户套接字:唯一定义了客户机进程
服务器套接字:唯一定义了服务器进程
传输层协议需要一对套接字地址:客户机套接字地址和服务器套接字地址。
IP头部:IP地址
UDP/TCP头部:端口号
传输层协议可以是无连接的或者是面向连接的服务。
分组从一方发给另一方,不需要建立连接和释放连接。
隐患:分组没有编号。可能延迟,丢失,无序到达。无确认过程。
UDP是无连接的。
面向连接的服务中,在发送方和接收方之间建立一个连接,然后传送数据,最后释放连接。
TCP和SCTP是面向连接的。
传输层的服务有可靠的和不可靠的,主要是使用可靠的协议或者是不可靠的协议实现的。
传输层服务
{
可靠服务
{
需求:应用层需要可靠性,那么使用可靠服务
传输层实现流量控制和差错控制
服务较慢或者更复杂
不可靠服务
{
需求:不需要可靠性,使用自己的流量和差错控制
需要快速服务或者本质特性不要求流量和差错控制(如,实时应用)
传输层服务
UDP:不可靠协议
TCP和SCTP:可靠协议
原因:
TCP使用滑动窗口协议实现差错控制和流量控制。
三种协议在TCP/IP协议簇中的位置。
TCP和UDP的应用场景:
(1)客户端和服务器需要多次交互才能实现特定功能。如接收邮件和发送邮件。
(2)接收的邮件需要分段传输。如浏览器访问网页时,网页中的图片和HTML文件需要分段后发送给浏览器,QQ传送文件时也需要分段,此时使用TCP协议
(1)客户端程序和服务器端程序通信,应用程序发送的数据包不需要分段。如域名解析时的请求报文和返回的解析结果。
(2)实时通信。
(3)多播或者广播。
用户数据报协议(UDP):无连接不可靠传输层协议。
UDP提供服务:
UDP优点:
UDP使用的熟知端口号:
UDP分组称为用户数据报 User datagram:8字节固定头部
用户数据报的字段:
源端口号
在源主机上运行的进程使用的端口号:16位。端口号范围为0-65535。
对于客户端:大多是情况下是临时端口号
服务器:大多数情况下是熟知端口号
目的端口号
和源端口号类似
总长度
16位字段,定义了用户数据报的总长度,头部加上数据。
总长度是65536.但是UDP数据报必须比这个小,UDP数据报存放在具有总长度为65536字节的IP数据报中。
实际上这个字段是没有必要的。IP数据报中有定义总长度字段。
UDP长度 = IP长度 - IP头部长度
UDP分组的校验和和IP以及ICMP校验和的计算不一样。UDP校验和包括三个部分:
U
D
P
校验和
{
伪头部
U
D
P
头部
从应用层来的数据
UDP校验和
IP分组头部的一部分,其中某些字段要填入0,用户数据报封装在IP分组中。
校验和的计算以及在用户数据报中包括的校验和都是可选的,如果不进行校验和的计算,那么这些字段就填入全1。
注意:校验和时全1是不可能的(想象一下,只有数据全是0时才会出现校验和是全1的情况,而这是不可能的)
无连接服务:UDP发送出去的每一个用户数据报都是独立的数据报,每个数据报之间没有关系。
用户数据报不进行编号。
不进行连接的建立和连接中止——每一个用户的数据报可以沿着不同的路径传递。
流量控制
UDP没有流量控制,没有窗口机制,如果到达的报文太多,接收方可能会溢出。
差错控制
UDP没有差错控制,假如接收方使用校验和检测出差错时,就丢弃
由于缺少流量控制和差错控制,使用UDP的进程必须要提供这些机制。
从一个进程发送到另一个进程,UDP协议就要将报文在IP数据报中进行封装和拆封。
端口的实现:队列与端口的实现是联系在一起的。
客户机端,进程启动时从OS请求一个端口号。
请求的端口号
{
有些实现创建一个入队列和一个出队列,与每一个进程相关联
有些只创建与每一个进程相关联的入队列
请求的端口号
note:如果一个进程想与多个进程通信,那么也只得到一个端口号,而最后也只有一个出队列outgoing queue和入队列 incoming queue。进程撤销时,队列撤销。
排队过程:
a.客户机的队列创建
客户机进程使用在请求中指明的源端口号将报文发送到出队列。UDP逐个将报文取出,加上UDP头部交给IP。
出队列可能会发生溢出,操作系统要求客户进程在继续发送报文之前要等待。
当报文到达客户端时,UDP检查一下确认用户数据报中的目的端口号字段指明的端口号有创建入队列。
入队列可能会溢出,溢出时向服务器发送端口不可达报文。
b.服务器的队列创建
最简单的形式:服务器在开始运行的时候就用熟知端口请求入队列和出队列。只要服务器运行,那么队列就一直是打开的。
UDP适用的应用如下:
传输控制协议Transmission Control Protocol:
TCP’s well known ports
TCP是面向流的协议。TCP允许发送进程以字节流 stream of bytes的形式传送数据。
TCP建立一种环境,两个进程好像是由一个假象的“管道”进行连接,管道通过因特网传输进程的数据。发送进程产生(写入)字节流,接收进程消费(读出)这些字节流。
由于发送和接收进程可能以不同的速度写入和读出数据,所以TCP需要用于存储的缓冲区。
每个方向都有一个缓冲区
缓冲区
{
发送缓冲区
{
空存储单元,可由发送进程填充
已经发送但未确认
将要发送的字节
接收缓冲区
{
空存储单元
接收到的存储单元,可以由接收进程读出
缓冲区
缓冲区用于实现TCP的流量控制和差错控制
实现缓冲的一种方法:使用循环数组;
缓冲区通常是上百或者上千个字节,取决于实现方法。
实际上缓冲区的大小也不一定是一样的。
IP层作为TCP服务的提供者,需要以分组的形式而不是以字节流的形式发送数据。
段:传输层中,TCP将多个字节分组合在一起成为一个分组。这个分组称为段。
TCP给每个段添加头部(控制目的),然后将该段传递给IP层。段被封装到IP数据报中,然后再进行传输。
这些段可能被无序接收,丢失,损坏和重发。均由TCP处理。
一切对接收进程透明。
数据可以在同一时间双向流动。每一方TCP都有发送和接收缓冲区,他们能在双向发送和接收段。
TCP是面向连接的协议。站点A的一个进程要发送和接收来自站点B的数据时,步骤如下:
TCP使用确认机制acknowledgment mechanism来检查数据是否安全和完整到达。
TCP的段没有段特有的段序号,TCP在段头采用序号(sequence number)和确认号(acknowledgement number)
字节序号byte number:TCP为每一个字节进行编号。
byte number的特点:
(1)序号 Sequence Number
TCP对发送的每一个段分配一个序号,每个段的序号是这个段中的第一个字节的序号。
当一个段携带数据和控制信息时,使用一个序号;如果一个段没有携带用户数据,那么逻辑上不定义序号。虽然字段存在,但是是毫无意义的。
(2)确认号 acknowledgment number
TCP通信是全双工的,每一方使用确认号来确认已经收到的字节。
确认号定义了该方预期接收的下一个字节的序号。确认号是累积的(累计确认):确认号 = 收到的最后一个字节 + 1 = 预期接收的下一个字节。
段
{
头部:
20
−
−
60
b
y
t
e
s
{
固定头部:
20
b
y
t
e
s
选项
应用层的数据
段

源端口地址Source port address:16位字段,定义发送方的端口号
目的端口地址Destination port address:16位字段,定义接收方的端口号
序列号 Sequence Number:32位字段,是段中的第一个字节的编号。
头部长度Header Length:4位字段,单位为4字节。头部的长度在20bytes到60bytes之间,因此,min = 0101 = 5,max = 1111 = 60
保留 reserved:保留,未使用
控制 control:定义了6种不同的控制位或者标记,同一时间可以设置一位或者多位
c
o
n
t
r
o
l
{
U
R
G
:
紧急指针有效,置
1
时表示数据紧急,将紧急数据放在段的开始
A
C
K
:确认有效
P
S
H
:请求急迫,发送端的
T
C
P
窗口不必等待窗口被填满,这个段包含的数据必须尽快地发送给解释程序
R
S
T
:连接复位
S
Y
N
:同步序列号
F
I
N
:终止连接
control
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kdOdPkEb-1664536156894)(https://cdn.jsdelivr.net/gh/Holmes233666/gitee-image@main/pictureStore/image-20211215153515680.png)]
网络层提供的服务不可靠,给传输层带来了很大的困难:
传输层需要解决的问题:
TCP是面向连接的协议:源端和目的端之间建立一条虚路径,属于一个报文的所有段沿着虚路径发送——有利于处理帧的丢失和丢失帧的重发。
IP不知道TCP的重新排序的过程。
面向连接的传输有三个阶段:
连接建立要解决的问题:
要使每一方都能确认对方的存在
允许双方协商参数
参数
{
最大报文长度
最大窗口大小
服务质量
参数
TCP:全双工,数据传输双方都需要对通信进行初始化,并得到对方的认可。
(例子背景:客户要与服务器建立连接),过程如下:
服务器请求被动打开:服务器告诉TCP,他已经准备好接收一个连接,称为请求被动打开passive open
客户机请求主动打开:想要与服务器进行通信的客户机告诉他的TCP,需要连接到特定的服务器,TCP进行三次握手的过程:
(1)客户发送第一个SYN段,这个段仅有SYN被置位,用于序列号同步。
SYN占用一个序列号。当数据开始传输时,序列号加1。(仅有ACK不会+1)
(2)服务器发送第二个段,两个标志位SYN和ACK被置位。表示另一方向通信的SYN段,并且用ACK标志表示对第一个SYN的确认,占用一个序列号
(3)客户机发送第三个段,仅仅是一个ACK段,用ACK标志和确认号序列表示已经收到的段。这个段的序列号与SYN段的序列号相同,ACK段没有占用任何序列号。
Note:
单独的ACK如果不携带数据,则它不占用序列号。
SYN不携带数据,但是占用一个序列号
SYN+ACK不携带数据,但是占用一个序列号
两个进程都发出主动打开的情况,极少发生。这种情况下,双方同时发出SYN+ACK段,在他们之间建立一条单独的连接。
SYN洪泛攻击:攻击者将大量的SYN段发送到一个服务器,在数据报中通过伪装IP地址假装这些段来自不同的客户端时就发生了这种情况。
属于拒绝服务供给,使服务器资源耗尽。
TCP某些实现有减轻SYN攻击影响的策略:
{
在短期内对请求的链接进行限制
过滤掉来自不需要的源地址的数据报
使用
c
o
o
k
i
e
推迟资源分配直到一个完整的链接建立
连接建立后可进行双向数据传输data transfer,客户机和服务器双方都发送数据和确认。
在段内携带确认时,也可以传输数据:数据捎带确认 data piggybacked with the data
非急迫情况
TCP使用缓冲区存储来自发送方应用程序的数据流。发送方TCP可以选择段的大小。接收方在数据到达时也将数据进行缓存。并在应用程序准备就绪或者是接收方TCP认为合适的时候就将这些数据传递给应用程序。灵活性增加了TCP的效率。
急迫情况
比如双方的应用进行交互式通信,总是希望接收方能够立即响应,数据的延迟传输和延迟传递是不可接受的。
PUSH置位时就表示这个段包含的数据必须尽快传送给应用程序,不需要等待更多的需求。
TCP可以选择使用或者不使用这个操作。
URG位置位,紧急数据放在段的开始。段的其他部分可以包含普通数据。
EXAMPLE:处理数据时异常终止数据Ctrl +C
交换数据的任一方均可关闭连接,通常由客户端发起。关闭连接的方法有两种:
{
三次握手
T
h
r
e
e
−
W
a
y
H
a
n
d
s
h
a
k
i
n
g
:大多数实现
带有半关闭选项的四次握手
H
a
l
f
−
C
l
o
s
e
(1)客户进程接收到关闭命令时,客户的TCP发送第一个段:FIN段,FIN段的FIN被置位。
FIN段可以携带客户机要发送的最后一个数据块。或者只是一个控制段。只是一个控制段时仅占用一个序列号。
(2)服务器TCP接收到FIN段后,通知他的进程,并发送第二个段:FIN+ACK段,证实它接收到来自客户端的FIN段,同时通告另一方连接关闭。这个段可以包含来自服务器的最后一个数据块。如果不携带数据,那么该段仅占用一个序列号。
(3)客户机TCP发送最后一段:ACK段。证实收到来自服务器的FIN段。包含了确认号,是来自服务器的FIN段的序号加1。该段不占用序列号。
half-close:当一端停止发送数据后,还可以继续接收数据。
任意一端可发送数据,但通常是由客户端发起的。
TCP使用滑动窗口处理流量控制
使用TCP窗口使数据传输更有效,同时控制数据流,使得目的端不至因为数据来得过多而瘫痪。TCP窗口是面向字节的。
滑动窗口的数据分类:
滑动窗口数据分类
{
左窗口外:已经发送且已经确认
窗口内
{
窗口内左侧:已经发送但未确认
窗口内右侧:可以立即发送
右窗口外:不满足发送条件,暂时不可发送
滑动窗口数据分类

动作分类
{
c
l
o
s
i
n
g
:得到确认
o
p
e
n
i
n
g
:运行缓冲区存储符合发送条件的更新的字节
s
h
i
n
k
i
n
g
:废除某些符合条件的字节发送
动作分类
TCP窗口大小取决于两个值中较小的一个: min { r w n d , c w n d } \min\{rwnd, cwnd\} min{rwnd,cwnd}
TCP的发送方不必发一个全窗口大小的数据。
TCP窗口的要点如下:
通知窗口是接收方根据接受能力确定的窗口。接收方将通知窗口的值放在报文首部发送给发送方。发送方根据接收方的工作状态改变窗口大小是TCP流量控制的主要方法。
如果接收方读取速度与到达速度一样,接收方在每一个确认中发送一个非零的窗口通告。如果发送方比接收方快,造成缓冲区全部被占用,那么接收方发送一个**“零窗口”通告**,发送方停止发送。直到收到一个非零窗口通告。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GDM2VVv8-1664536156901)(https://cdn.jsdelivr.net/gh/Holmes233666/gitee-image@main/pictureStore/image-20211215215602450.png)]
非零窗口通告可能会丢失,TCP为每个连接设置了一个坚持计时器,当发送方收到零窗口确认时,就启动坚持计时器。计时器到期后,发送探测报文,提醒接收方确认报文已经丢失。
如果TCP缓存已满,而应用进程每次只从缓存读取一个字节。向发送窗口发送为1的确认报文,此时发送方会以41字节的代价发送1字节的数据。这样下去,传输效率及低。
解决方法是禁止接收方发送只有1个字节的更新报文,接收方会等待一定的时间,使得收取缓存有足够空间接收一个较长的报文,再发送窗口更新报文。
TCP的差错控制包括检测出报文的差错,丢失,失序和重复并纠正。
差错检测和纠正的方式
{
校验和
C
h
e
c
k
s
u
m
确认
A
c
k
n
o
w
l
e
d
g
e
重传
R
e
t
r
a
n
s
m
i
s
s
i
o
n
差错检测和纠正的方式
如果段受到损坏,那么将被目的端TCP丢弃,并且认为是丢失了。TCP在每段中强制使用一个16位的校验和。
TCP使用确认来证实已经收到了数据段。不携带数据但是占用序列号的一些控制段也要确认,但单独的ACK段是不需要确认的。
TCP对所有重要的段(已经发送但是还未确认)使用一个重传超时计时器。
当计时器到时时,即使可能是由于段被延迟,ACK被延迟或者是ACK被丢失等未接收到ACK时,重发一个最早的重要的段。
仅仅含有ACK的段没有设置超时计时器,这样的段不需要重发。
RTO的值是动态的,根据段的往返时间(Round-Trip Time)进行更新。
收到3个重复的ACK。在重传计时器超时之前进行重传。
当一个段被延迟、丢失或者废弃,后面到达的段就失序了。
{
T
C
P
原先设计:丢弃失序的段,并且重传失序段后面的段
T
C
P
现在设计:
{
不丢弃失序的段,标记他们为失序,直到缺少的段到达
这些失序的段不传递给进程,
T
C
P
确保数据按序传递给进程
TCP对于丢失的段和损坏的段做同样的处理。
丢失段在网络某处丢失,损坏段被接收方本身丢弃。
TCP在间隙指明数据存在不连续性,在这个间隙被填充之前不将这个字节传递给应用程序。
收到三个连续的同样序号的ACK时,不必等待RTO计时器过期,立即重传期待帧
网络中的载荷即发送到网络中分组的数量,超过了网络的容量,在网络中就有可能发生拥塞。
发送方维护一个拥塞窗口cwnd,且动态变化。发送方让自己的发送窗口小于等于cwnd。
TCP的拥塞策略基于三个阶段:
慢启动使用
窗口慢速启动,但是按照指数规则增长。
EXAMPLE:假设使用段的个数而不是字节的个数(好像每个段只有一个字节);
假定rwnd比cwnd大得多,这样发送窗口永远小于等于cwnd。
假设每个段都是单独确认的。
按照传输次数观察cwnd的大小(整个窗口中的段被确认),则发现其速率是按照指数的规则增长。数据增长的规律:
开始:cwnd = 1
第一次传输:cwnd = 2
第二次传输:cwnd = 4
第三次传输:cwnd = 8
如果有延迟的ACK,那么窗口的增长小于2的幂。
慢速启动不能一直持续下去,达到阈值时必须停止该阶段。发送方保存一个称为ssthresh(慢启动阈值)的变量。
当拥塞窗口中的字节达到阈值时,开始下一个阶段,ssthresh的值是2^16字节
拥塞避免的目的:在拥塞发生之前降低指数增长的速度。这个算法是加性增加,而不是指数增加。
加性增加:每次整个窗口的所有的段都被确认时,拥塞窗口才加1。(直到检测到数据丢失)
按照传输的次数观察cwnd的大小,则发现其速率是按照加性规律增长:
能够检测到拥塞唯一方法是通过重传段的要求
{
严重情况:
R
T
O
计时器到期
接收到三个
A
C
K
RTO计时器到时:非常严重的拥塞的可能性
策略总结:
策略
{
R
T
O
超时
{
阈值变为当前拥塞窗口大小一半
设置
c
w
n
d
为
1
个段的大小
开启慢启动状态
收到三个
A
C
K
{
阈值变为当前拥塞窗口的一半
拥塞窗口值为阈值
开启拥塞避免状态
策略
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xy65vrBL-1664536156902)(https://cdn.jsdelivr.net/gh/Holmes233666/gitee-image@main/pictureStore/image-20211218161500989.png)]
特点:
多流的概念:
多端口的概念:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h8aMvXOb-1664536156902)(https://cdn.jsdelivr.net/gh/Holmes233666/gitee-image@main/pictureStore/image-20211218161829080.png)]
在SCTP中,数据大块按照传输序列号编号。控制信息和数据信息在分开的数据大块中携带。
为了别不同的流,SCTP使用SI。(流标识符)