TCP(Transmission ControlProtocol)与UDP(User Datagram Protocol)
TCP提供可靠的通信传输, 而UDP则常被用于让广播和细节控制交给应用的通信传输
传输层
- 定义
IP首部中有一个协议字段, 用来标识网络层(IP)的上一层所采用的是哪一种传输层协议.
根据这个字段的协议号, 就可以识别IP传输的数据部分究竟是TCP的内容, 还是UDP的内容.
同样, 传输层的TCP和UDP, 为了识别自己所传输的数据部分究竟应该发给哪个应用,
也设定了这样一个编号, 也就是端口号这样一种识别码 - 通信处理
TCP/IP的众多应用协议大多以客户端/服务端的形式运行.
- 客户端(客户端(Client)具有客户的意思.在计算机网络中是提供服务和使用服务的一方)
类似于客户的意思, 是请求的发起端. - 服务端(服务端(Server)在计算机网络中则意味着提供服务的程序或计算机)
则表示提供服务的意思, 是请求的处理端.另外, 作为服务端的程序有必要提前启动, 准备接收客户端的请求 - 服务端程序在UNIX系统当中叫做守护进程.
例如HTTP的服务端程序是httpd(HTTP守护进程), 而ssh的服务端程序是sshd(SSH守护进程).
在UNIX中并不需要将这些守护进程逐个启动, 而是启动一个可以代表它们接收客户端请求的inetd(互联网守护进程)服务程序.
它是一种超级守护进程.该超级守护进程收到客户端请求以后会创建(fork)新的进程并转换(exec)为sshd等各个守护进程 - 确认一个请求究竟发给的是哪个服务端(守护进程), 可以通过所收到数据包的目标端口号轻松识别
- 两种传输层协议TCP和UDP
- TCP
TCP是面向连接的、可靠的流协议.流就是指不间断的数据结构, 你可以把它想象成排水管道中的水流.
当应用程序采用TCP发送消息时, 虽然可以保证发送的顺序, 但还是犹如没有任何间隔的数据流发送给接收端
(发送端发送10次100字节, 服务端可以只接受1次1000字节)
TCP为提供可靠性传输, 实行“顺序控制”或“重发控制”机制.此外还具备“流控制(流量控制)”、“拥塞控制”、提高网络利用率等 - UDP
UDP是不具有可靠性的数据报协议.细微的处理它会交给上层的应用去完成.
在UDP的情况下, 虽然可以确保发送消息的大小却不能保证消息一定会到达
- TCP与UDP区分
TCP用于在传输层有必要实现可靠传输的情况.由于它是面向有连接并具备顺序控制、重发控制等机制的,
所以它可以为应用提供可靠传输
UDP主要用于那些对高速传输和实时性有较高要求的通信或广播通信
- 套接字(Socket)
应用在使用TCP或UDP时, 会用到操作系统提供的类库.
这种类库一般被称为API(Application Programming Interface, 应用编程接口).
使用TCP或UDP通信时, 又会广泛使用到套接字(socket)的API.
应用程序利用套接字, 可以设置对端的IP地址、端口号, 并实现数据的发送与接收
端口号
- 定义
数据链路和IP中的地址, 分别指的是MAC地址和IP地址.
前者用来识别同一链路中不同的计算机, 后者用来识别TCP/IP网络中互连的主机和路由器.
在传输层中也有这种类似于地址的概念, 那就是端口号.端口号用来识别同一台计算机中进行通信的不同应用程序.
因此, 它也被称为程序地址 - 通过IP地址、端口号、协议号进行通信识别
TCP/IP或UDP/IP通信中通常采用5个信息来识别(netstat -n) 一个通信.
它们是“源IP地址”、“目标IP地址”、“协议号”、“源端口号”、“目标端口号”.只要其中某一项不同, 则被认为是其他通信
源IP地址: 区分两台计算机
源端口号: 打开两个Web浏览器, 同时访问两个服务器上不同的页面, 就会在这个浏览器跟服务器之间产生类似前面的两个通信
协议号: IP地址和端口全都一样, 只是协议号(表示上层是TCP或UDP的一种编号)不同
[外链图片转存失败(img-4XRYjEPg-1567931050109)(images/通信识别.png)] - 端口号如何确定
标准既定的端口号(静态方法):
关于知名端口号以及注册端口号的最新消息:http://www.iana.org/assignments/port-numbers
协议 | TCP server端口号 | client端口号 |
---|---|---|
HTTP | 80 | 2001 |
HTTPS | 443 | |
FTP | 21 | 2000 |
SSH | 22 | |
SMTP | 25 |
时序分配法 (或动态分配法):
此时, 服务端有必要确定监听端口号, 但是接受服务的客户端没必要确定端口号
操作系统可以为每个应用程序分配互不冲突的端口号,例如, 每需要一个新的端口号时, 就在之前分配号码的基础上加1
动态分配的端口号取值范围在49152到65535之间
4. 端口号与协议
端口号由其使用的传输层协议决定.因此, 不同的传输协议可以使用相同的端口号
例如, TCP与UDP使用同一个端口号, 但使用目的各不相同.这是因为端口号上的处理是根据每个传输协议的不同而进行的
这是因为, 数据到达IP层后, 会先检查IP首部中的协议号, 再传给相应协议的模块
UDP
UDP是User Datagram Protocol的缩写.(UDP的“用户”(User)其实就相当于程序员)
- UDP不提供复杂的控制机制, 利用IP提供面向无连接的通信服务.
并且它是将应用程序发来的数据在收到的那一刻, 立即按照原样发送到网络上的一种机制. - UDP也无法进行流量控制等避免网络拥塞的行为.
- 此外, 传输途中即使出现丢包, UDP也不负责重发.
- 甚至当出现包的到达顺序乱掉时也没有纠正的功能.如果需要这些细节控制, 那么不得不交由采用UDP的应用程序去处理
- UDP按照“制作程序的那些用户的指示行事”.
- UDP面向无连接, 它可以随时发送数据.再加上UDP本身的处理既简单又高效, 因此经常用于以下几个方面:
包总量较少的通信(DNS、SNMP等)
视频、音频等多媒体通信(即时通信)
限定于LAN等特定网络中的应用通信
广播通信(广播、多播)
TCP
TCP可以说是对“传输、发送、通信”进行“控制”的“协议”.
- 它可以进行丢包时的重发控制,
- 还可以对次序乱掉的分包进行顺序控制
- 此外, TCP作为一种面向有连接的协议, 只有在确认通信对端存在时才会发送数据, 从而可以控制通信流量的浪费
根据TCP的这些机制, 在IP这种无连接的网络上也能够实现高可靠性的通信
- TCP的特点及其目的
TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输 - 通过序列号与确认应答实现可靠传输
在TCP中, 当发送端的数据到达接收主机时, 接收端主机会返回一个已收到消息的通知.这个消息叫做确认应答
(ACK(ACK(PositiveAcknowled-gement)意指已经接收)
- 在一定时间内没有等到确认应答, 发送端就可以认为数据已经丢失, 并进行重发.
由此, 即使产生了丢包, 仍然能够保证数据能够到达对端, 实现可靠传输 - 未收到确认应答并不意味着数据一定丢失.也有可能是数据对方已经收到, 只是返回的确认应答在途中丢失
源发送主机只要按照机制重发数据即可, 接收主机接收到相同数据时会丢弃掉 - 为此, 就必须引入一种机制, 它能够识别是否已经接收数据, 又能够判断是否需要接收
上述这些确认应答处理、重发控制以及重复控制等功能都可以通过序列号实现
序列号是按顺序给发送数据的每一个字节(8位字节)都标上号码的编号
(序列号的初始值并非为0.而是在建立连接以后由随机数生成.而后面的计算则是对每一字节加一)
接收端查询接收数据TCP首部中的序列号和数据的长度, 将自己下一步应该接收的序号作为确认应答返送回去.
就这样, 通过序列号和确认应答号, TCP可以实现可靠传输
- 重发超时如何确定
重发超时是指在重发数据之前, 等待确认应答到来的那个特定时间间隔.如果超过了这个时间仍未收到确认应答, 发送端将进行数据重发
- TCP要求不论处在何种网络环境下都要提供高性能通信, 并且无论网络拥堵情况发生何种变化, 都必须保持这一特性.
为此, 它在每次发包时都会计算往返时间(Round Trip Time也叫RTT.是指报文段的往返时间)
及其偏差(RTT时间波动的值、方差.有时也叫抖动)将这个往返时间和偏差相加重发超时的时间, 就是比这个总和要稍大一点的值. - 重发超时的计算既要考虑往返时间又要考虑偏差是有其原因.根据网络环境的不同往返时间可能会产生大幅度的摇摆,
之所以发生这种情况是因为数据包的分段是经过不同线路到达的.TCP/IP的目的是即使在这种环境下也要进行控制, 尽量不要浪费网络流量
- 连接管理
TCP提供面向有连接的通信传输.面向有连接是指在数据通信开始之前先做好通信两端之间的准备工作
- 在数据通信之前, 通过TCP首部发送一个SYN包作为建立连接的请求等待确认应答
(TCP中发送第一个SYN包的一方叫做客户端, 接收这个的一方叫做服务端)
如果对端发来确认应答, 则认为可以进行数据通信.如果对端的确认应答未能到达, 就不会进行数据通信.
此外, 在通信结束时会进行断开连接的处理(FIN包) - 可以使用TCP首部用于控制的字段来管理TCP连接(也叫控制域)
- 一个连接的建立与断开, 正常过程至少需要来回发送7个包才能完成
- 建立一个TCP连接需要发送3个包.这个过程也称作“三次握手”
client向server发起SYN请求连接
server针对SYN返回ACK, 同时server发起SYN, 请求与client建立连接, 此时ACK和SYN是在一个连接中
最后client向server发送ACK确认SYN - 断开一个TCP连接
client向server发起FIN请求断开连接
server针对SYN返回ACK, 经过对连接中请求进行处理后
server发起FIN, 请求与client切断连接, CK和SYN是在两个连接中
最后client向server发送ACK确认FIN
- 建立一个TCP连接需要发送3个包.这个过程也称作“三次握手”
- TCP以段为单位发送数据
在建立TCP连接的同时, 也可以确定发送数据包的单位, 我们也可以称其为“最大消息长度”(MSS:Maximum Segment Size)
最理想的情况是, 最大消息长度正好是IP中不会被分片处理的最大数据长度
- MSS是在三次握手的时候, 在两端主机之间被计算得出.
两端的主机在发出建立连接的请求时, 会在TCP首部中写入MSS选项, 告诉对方自己的接口能够适应的MSS的大小
然后会在两者之间选择一个较小的值投入使用
- 利用窗口控制提高速度
TCP以1个段为单位, 每发一个段进行一次确认应答的处理,下一次的处理要等到收到当前应答后才开始,
这样的传输方式有一个缺点.那就是, 包的往返时间越长通信性能就越低.
- 为解决这个问题, TCP引入了窗口这个概念.即使在往返时间较长的情况下, 它也能控制网络性能的下降
确认应答不再是以每个分段, 而是以更大的单位进行确认时, 转发时间将会被大幅度的缩短.
也就是说, 发送端主机, 在发送了一个段以后不必要一直等待确认应答, 而是继续发送
窗口大小就是指无需等待确认应答而可以继续发送数据的最大值
这个机制实现了使用大量的缓冲区(缓冲区(Buffer)在此处表示临时保存收发数据的场所.
通常是在计算机内存中开辟的一部分空间) , 通过对多个段同时进行确认应答的功能 - 为了实现重发, 发送端主机在等到确认应答返回之前, 必须在缓冲区中保留这部分数据, 直到收到确认应答
- 滑动窗口控制
收到确认应答的情况下, 将窗口滑动到确认应答中的序列号的位置.这样可以顺序地将多个段同时发送提高通信性能.
- 窗口控制与重发控制
- 确认应答未能返回
数据已经到达对端, 是不需要再进行重发的.
使用了窗口控制, 即使少部分的确认应答丢失也不会数据重发, 可以通过下一个确认应答进行确认 - 某个报文段丢失
当某一报文段丢失后, 发送端会一直收到序号为1001的确认应答, 这个确认应答好像在提醒发送端“我想接收的是从1001开始的数据”.
因此, 在窗口比较大, 又出现报文段丢失的情况下, 同一个序号的确认应答将会被重复不断地返回.
而发送端主机如果连续3次收到同一个确认应答(之所以连续收到3次而不是两次的理由是因为, 即使数据段的序号被替换两次也不会触发重发机制) ,
就会将其所对应的数据进行重发, 这种机制比之前提到的超时管理更加高效, 因此也被称作高速重发控制
- 流控制
接收端忙于处理其他请求, 暂时无法接受数据, 将本应该接收的数据丢弃的话, 就又会触发重发机制.
- 为了防止这种现象的发生, TCP提供一种机制可以让发送端根据接收端的实际接收能力控制发送的数据量.这就是所谓的流控制
- 它的具体操作是, 接收端主机向发送端主机通知自己可以接收数据的大小, 于是发送端会发送不超过这个限度的数据.该大小限度就被称作窗口大小
- TCP首部中, 专门有一个字段用来通知窗口大小.接收主机将自己可以接收的缓冲区大小放入这个字段中通知给发送端.
这个字段的值越大, 说明网络的吞吐量越高 - 发送端主机会根据接收端主机的指示, 对发送数据的量进行控制.这也就形成了一个完整的TCP流控制(流量控制)
- 拥塞控制
在网络出现拥堵时, 如果突然发送一个较大量的数据, 极有可能会导致整个网络的瘫痪.
TCP为了防止该问题的出现, 在通信一开始时就会通过一个叫做慢启动的算法得出的数值, 对发送数据量进行控制
- 为了在发送端调节所要发送数据的量, 定义了一个叫做“拥塞窗口”的概念
- 慢启动的时候, 将这个拥塞窗口的大小设置为1个数据段(1MSS)发送数据, 之后每收到一次确认应答(ACK), 拥塞窗口的值就加1.
在发送数据包时, 将拥塞窗口的大小与接收端主机通知的窗口大小做比较, 然后按照它们当中较小那个值, 发送比其还要小的数据量. - 如果重发采用超时机制, 那么拥塞窗口的初始值可以设置为1以后再进行慢启动修正
- 慢启动阀值
为了防止拥塞窗口增加的过快导致网络拥塞, 只要拥塞窗口的值超出这个阀值, 在每收到一次确认应答时, 只允许以下面这种比例放大拥塞窗口
(1个数据段的字节数/拥塞窗口字节数)*1个数据段的字节数
TCP的通信开始时, 并没有设置相应的慢启动阀值(与窗口的最大值相同) 而是在超时重发时, 才会设置为当时拥塞窗口一半的大小. - 由重复确认应答而触发的高速重发与超时重发机制的处理多少有些不同.
因为前者要求至少3次的确认应答数据段到达对方主机后才会触发, 相比后者网络的拥堵要轻一些
重复确认应答进行高速重发控制时, 慢启动阀值的大小被设置为当时窗口大小的一半.然后将窗口的大小设置为该慢启动阀值+3个数据段 - 当TCP通信开始以后, 网络吞吐量会逐渐上升, 但是随着网络拥堵的发生吞吐量也会急速下降.于是会再次进入吞吐量慢慢上升的过程.
因此所谓TCP的吞吐量的特点就好像是在逐步占领网络带宽的感觉
- 提高网络利用率的规范
- Nagle算法
该算法是指发送端即使还有应该发送的数据, 但如果这部分数据很少的话, 则进行延迟发送的一种处理机制
具体来说, 就是仅在下列任意一种条件下才能发送数据. -
- 已发送的数据都已经收到确认应答时
-
- 可以发送最大段长度(MSS)的数据时
根据这个算法虽然网络利用率可以提高, 但是可能会发生某种程度的延迟
- 可以发送最大段长度(MSS)的数据时
- 延迟确认应答
接收数据的主机如果每次都立刻回复确认应答的话, 可能会返回一个较小的窗口.那是因为刚接收完数据, 缓冲区已满.
当某个接收端收到这个小窗口的通知以后, 会以它为上限发送数据, 从而又降低了网络的利用率
为此, 引入了一个方法, 那就是收到数据以后并不立即返回确认应答, 而是延迟一段时间的机制 -
- TCP采用滑动窗口的控制机制, 因此通常确认应答少一些也无妨.
TCP文件传输中, 绝大多数是每两个数据段返回一次确认应答.
- TCP采用滑动窗口的控制机制, 因此通常确认应答少一些也无妨.
- 捎带应答
TCP的确认应答和回执数据可以通过一个包发送.这种方式叫做捎带应答.
不过确认应答必须得等到应用处理完数据并将作为绘制的数据返回为止, 才能进行捎带应答
接收数据以后如果立刻返回确认应答, 就无法实现捎带应答.
如果需要应用自己处理一些更为细节上的控制, 使用UDP协议是不错的选择.
如果转发数据量较多、对可靠性的要求比较高时, 可以选择使用TCP
其他传输层协议
- UDP-Lite
UDP-Lite(Lightweight User Datagram Protocol, 轻量级用户数据报协议)是扩展UDP机能的一种传输层协议
在基于UDP的通信当中如果校验和出现错误, 所收到的包将被全部丢弃
UDP-Lite提供与UDP几乎相同的功能, 不过计算校验和的范围可以由应用自行决定 - SCTP
SCTP(Stream Control Transmission Protocol, 流控制传输协议)
(SS7协议最初被应用于TCP/IP上时, 由于TCP本身使用起来不是很方便, 所以人们开发了SCTP协议.今后它可能会出现各种各样的使用途径)
与TCP一样, 都是对一种提供数据到达与否相关可靠性检查的传输层协议
其主要特点如下:
以消息为单位收发
TCP中接收端并不知道发送端应用所决定的消息大小.在SCTP中却可以.
支持多重宿主
在有多个NIC的主机中, 即使其中能够使用的NIC发生变化, 也仍然可以继续通信(这与TCP相比提高了故障应对能力)
支持多数据流通信
TCP中建立多个连接以后才能进行通信的效果, 在SCTP中一个连接就可以.(吞吐量得到有效提升)
可以定义消息的生存期限
超过生存期限的消息, 不会被重发.
SCTP主要用于进行通信的应用之间发送众多较小消息的情况.这些较小的应用消息被称作数据块(Chunk), 多个数据块组成一个数据包.
此外, SCTP具有支持多重宿主以及设定多个IP地址的特点.
多重宿主是指同一台主机具备多种网络的接口.例如, 笔记本电脑既可以连接以太网又可以连接无线LAN. - DCCP
DCCP(Datagram Congestion Control Protocol, 数据报拥塞控制协议)是一个辅助UDP的崭新的传输层协议.
UDP没有拥塞控制机制.为此, 当应用使用UDP发送大量数据包时极容易出现问题.互联网中的通信, 即使使用UDP也应该控制拥塞
首部的格式
- UDP: 源端口号(Source Port),目标端口号(Destination Port), 包长度(Length), 校验和(Checksum)
UDP数据报没有IP地址这极有可能会导致应该收包的应用收不到包, 不该收到包的应用却收到了包
所以, 接收主机在收到UDP数据报以后, 从IP首部获知IP地址信息构造UDP伪首部, 再进行校验和计算. - TCP