58.1 互联网
互联网会将不同的计算机网络连接起来并允许位于网络中的主机相互之间进行通信。
互联网的目标是隐藏不同物理网络的细节以便向互联网中的所有主机呈现一个统一的网络架构,TCP/IP已经成了使用最为广泛的协议套件了,
术语Internet被用来指将全球成千上万的计算机连接起来的TCP/IP互联网。
一台路由器拥有多个网络接口,每个接口都连接到一个子网上。
术语"多宿主机"用来指拥有多个网络接口的任意主机---不必是一台路由器。
一个多宿主机的各个接口上的网络地址是不同的。
https://baijiahao.baidu.com/s?id=1784973165193699993\&wfr=spider\&for=pc
58.2 联网协议和层
TCP/IP协议套件是一个分层联网协议它包括因特网协议(IP)和位于其上层的各个协议层。名字TCP/IP是从传输控制协议(TCP)是使用最为广泛的传输层协议这样一个事实而的出来的。
地址解析协议(ARP)关注的是如何将因特网地址映射到硬件地址。
因特网控制消息协议(ICMP)用来在网络中传输错误和控制信息。
(ping和traceroute程序使用的就是ICMP协议,人们通常使用ping来检查一台特定的主机是否存活以及是否在TCP/IP网络中可见,使用traceroute来跟踪一个IP包在网络中的传输路径。)
主机和路由器使用因特网组管理协议(IGMP)来支持数据报的多播
协议分层如此强大和灵活,是透明---每一个协议层都对上层隐藏下层的操作和复杂性。
应用程序也无需知IP和数据链路层的操作细节。
封装
封装是分层互联网协议中的一个重要原则。
给出了TCP/IP协议层中的封装。
1、封装中的关键概念是低层会将从高层向低层传递的信息当成不透明的数据来处理。
2、底层不会尝试对高层发送过来的信息进行解释。
3、 将这些信息放到低层所使用的包中并在这个包向下传递到低层之前添加自身这一层的头信息。
4、 当数据从低层传递到高层时将会进行一个逆向的解包过程。
封装的概念还延伸到了数据链路层,其中IP数据报会被封装进网络帧中,封装可能还会延伸到应用层中,其中应用程序可能会按照自己的方式对数据进行打包
58.3 数据链路层
最低层是数据链路层,他是由设备驱动和底层物理媒介的硬件接口。
数据链路层关注的时在一个网络的物理连接上传输数据。
需要将网络层传递过来的数据报封装进被称为帧的一个一个单元。
每个帧都会包含一个头,如头中可能包含了目标地址和帧的大小。
数据链路层在物理连接上传输帧并处理来自接受者的确认。
这一层可能会进行错误检测、重传以及流量控制。
将大的网络包分成多个帧并在接受者端将这些帧进行重组。
所有的通信细节都是由驱动和硬件来处理的。
数据链路层,特点是最大传输单元(MTU),是该层所能传输的帧大小的上限,
不同的数据链路层的MTU是不同的。
命令 netstat -i 会列出系统中所有的网络接口,包括 MTU.
(base) wannian07@wannian07-PC:~/Desktop$ netstat -i
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
lo 65536 3961 0 0 0 3961 0 0 0 LRU
wlp1s0 1500 364 0 18 0 210 0 242 0 BMU
58.4 网络层:IP
位于数据链路层之上是网络层,将包(数据)从源主机发送到目标主机。
任务:
1、将数据分解成足够小的片段以便数据链路层进行传输
2、 在因特网上路由数据
3、为传输层提供服务
在TCP/IP协议套件中,
IPv4使用32位地址来标识子网和主机,
IPv6则使用了128位的地址,从而能为主机提供更大的地址范围。
IPv4地址空间的枯竭是创造IPv6主要原因
一个裸socket(SOCK_RAW),他允许应用程序直接与IP层进行通信。
IP传输数据报
IP以数据报(包)的形式来传输数据。
每一个数据都是在网络上独立传输的,他们经过的路径可能会不同。
一个IP数据包含一个头,其大小范围是20个字节到60个字节。
包含了目标主机的地址,这样就可以在网络上将这个数据报路由到目标地址了,
包含了包的源地址,这样就收主机就知道数据报的源头。
一个IP设定一个上限,所有IP实现都必须做到数据报的大小上限至少与规定的IP最小重组缓冲区大小一样大。
在IPv4中这个限制是576字节;在IPv6中,这个限制是1500字节
IP是无连接和不可靠的
IP 是一种无连接协议
IP也是一种不可靠的协议:他尽最大可能将数据报从发送者传送给接收者,
不保证包到达的顺序与他们传输的顺序一样,
也不保证是否重复,
不保证包是否会到达接收者。
IP也没有提供错误恢复
可靠性是通过使用一个可靠的传输协议(如TCP)或者应用程序本身来保证的。
IPv4为IP头提供了一个校验和,检测出头部的错误
IPv6 并没有为IP头提供校验和,他一来高层协议来完成错误检测和可靠性。
UDP校验和在IPv6是强制的。
TCP校验和在IPV4和IPv6中都是强制的
IP数据包的重复是可能发生的。
IP可能会对数据报进行分段
IPv4数据报的最大大小为65535字节。
IPv6允许一个数据报的最大大小为65575字节
(40个字节用于存放头信息,65535自己用于存放数据)
IP的路径MTU概念,他是源主机到目的主机之间路由上的所有数据链路层的最小MTU。
当一个IP数据报的大小大于MTU时,IP数据报会分段(分解)成一个个大小适合在网络上的传输单元。这些分段在达到最终目的地之后会被重组成原始的数据报
IP分段的发生对于高层协议时透明的。UDP并没有提供这种机制。
58.5 IP地址
一个IP地址分为两个部分:
一个是网络ID,它指定了主机所属的网络;
另一个是主机ID,它标识了位于该网络中的主机。
IPv4 地址
一个IPv4地址包含32位。地址通常采用点分十进制标记法,即将地址的四个字节写成一个十进制数字,中间以点号隔开。
当一个组织为其主机申请一组IPv4地址时,他会收到一个32位的网络地址以及一个对应的32位的网络掩码。
这些1表示地址中哪些部分包含了所分配到的网络ID,
这些0则表示地址中哪些部分可供组织用来为网络中的主机分配唯一的ID。
掩码中网络ID部分的大小会在分配地址时确定。由于网络ID部分总是占据着掩码最左边的部分,因此可以使用下面的标记法拉指定分配的地址范围。
204.152.189.0/24
这里的/24表示的分配的网络ID 由最左边的24位构成,剩余的8位用于指定主机ID。或者在这种情况下也可以说网络掩码的点分十进制标记时255.255.255.0.
拥有这个地址的组织可以见254个唯一的因特网地址分配给计算机---204.152.189.1到204.152.189.254。
两个地址是无法分配给计算机的:
一个地址的主机ID的位都是0,它用来表示网络本身,
另一个地址的主机ID位都是1----在本例中204.152.189.255-----他是子网广播地址。
一些IPv4地址拥有特殊含义。
特殊地址127.0.0.1一般被定义为回环地址,它通常会被分配给主机名localhost.(网络 127.0.0.0/8中的所有地址都可以被指定为IPv4回环地址,但通常会选择127.0.0.1.)发送到这个地址的数据报实际上不会到达网络,他会自动会还变成发送主机的输入。使用这个地址可以便捷的在同一主机上测试客户端和服务器程序。在C程序中定义了INADDR_LOOPBACK来表示这个程序。
常量INADDR_ANY就是所谓的IPv4通配地址。
通配IP地址对于将Internet domain socket 绑定到多宿主机上的应用程序来讲是比较有用的。如果位于一台多宿主机上的应用程序只将socket绑定到其中一个主机IP地址上,那么该socket就只能接收该IP地址上的UDP数据和TCP连接请求。但一般来讲都希望一台多宿主机上的应用程序能够接收指定任意一个主机IP地址的数据报和连接请求,而将socket绑定到统配IP地址上使之成为了可能。
一般来讲,IPv4是划分子网的。
划分子网将一个IPv4地址的主机ID部分分成两个部分:
一个子网ID
一个主机ID
子网划分原理在于一个组织通常不会将其所有主机接到单个网络。
组织可能会开启一组子网,每个子网使用网络ID和子网ID组合起来标识。
这种组合通常被称为扩展网络ID。在一个子网中,子网掩码所扮演的角色与之前描述的网络掩码的角色是一样的,并且可以使用类似的标记法来标识分配给一个特定子网的地址范围。
IPv6地址
IPv6地址是由128位构成,其中地址的前面一些位是一个格式前缀,表示地址类型
IPv6地址通常被书写成一系列用冒号隔开的16位的十六进制数字,如下所示。 F000:0:0:0:0:0:A:1
IPv6通常包含一个0序列,并且为了标记方便,可以使用两个分号(::)来表示这种序列。因此上面的地址可以被重写成:F000:A:1
在IPv6地址中智能出现一个双冒号标记,出现多次的话会造成混淆。
IPv6地址也想IPv4那样提供了环回地址(127个0后面跟一个1即 ::1)和通配地址(所有都为0,可以书写为0::0)
为允许IPv6应用程序与只支持IPv4的主机进行通信,IPv6提供了所谓的IPv4映射的IPv6地址,
IPv4映射的IPv6地址形式
在书写IPv4地址映射的IPv6地址时,地址的IPv4地址部分(即最后4个字节)会被书写成IPv4的点分十进制标记。因此与204.152.189.116等价的IPv4映射的IPv6地址是::FFFF: 204.152.189.116。
58.6 传输层
在TCP/IP套件中使用最广的两个传输层协议如下。
用户数据报协议(UDP)是数据报socket所使用的协议。
传输控制协议(TCP)是流socket所使用的协议。
58.6.1 端口号
传输层协议的任务是向位于不同主机(或有时候位于同一主机)上的应用程序提供端到端的通信任务。为完成这个任务,传输层需要采用已汇总方法来区分一个主机上的应用程序。在TCP和UDP中,这种区分工作是通过一个16位的端口号来完成的。
众所周知的、注册的以及特权端口
有些众所周知的端口号已经被永久地非陪给特定地应用程序了(也成为服务)。例如ssh(安全地shell)daemon使用众所周知地端口22,
HTTP(Web和服务器之间通信时所使用地协议)使用众所周知地端口80.
众所周知的端口号位于0~1023之间。它是由中央授权机构互联网号码分配局(IANA)来分配的。一个众所周知的端口号的分配是有一个被核准的网络规范(通常以RFC形式)来规定的。
IANA还记录着注册端口,IANA注册的端口范围为1024~41951。
IANA众所周知的更新列表和注册端口分配情况可以在http://www.iana.org/assignments/port-numbers上找到。
在大多数TCP/IP实现(包括Linux)中,范围在0~1023间的端口号也是特权端口,这意味着只有特权(CAP_NET_BIND_SERVICE)进程可以绑定到这些端口上2,从而防止了普通用户实现恶意程序
临时端口
如果一个程序没有选择一个特定的端口(即在socket术语中,他没有调用bind()将其socket绑定到一个特定的端口上),那么TCP和UDP会为该socket分配一个临时端口(即存活时间较短)。在这种情况下应用程序---通常是一个客户端---并不关心它所使用的端口号,但分配一个端口对于传输层协议标识通信端点来讲是有必要的。这种做法的另一个结果就是位于通信信道另一端的对等应用程序就知道如何与这个应用程序进行通信了。TCP和UDP在将socket绑定到端口0上时也会分配一个临时端口号。
IANA将位于49152到65535之间的端口称为动态或私有端口,这表示这些端口可供本地应用程序使用或作为临时端口分配。然后不同的实现可能会在不同的范围内分配临时端口。在linux上,这个范围是由包含在文件/proc/sys/net/ipv4/ip_local_port_range中的两个数字来定义的(可通过修改这两个值来修改范围)。
58.6.2 用户数据报协议(UDP)
UDP仅仅在IP上添加了两个特性:端口号和一个进行检测传输数据错误的数据校验和。
与IP一样,UDP也是无连接的。
UDP和TCP使用校验和长度只有16位并且只是简单的"总结性"校验和,因此无法检测出特定的错误,其结果是无法提供较强的错误检测机制。
确保数据完整性的应用程序可以使用安全Sockets层(Secure Sockets Layer,SSL),它不仅提供了安全的通信,而且还提供更加严格的错误检测过程。或者应用程序也可以实现自己的错误控制机制。
选择一个UD[数据报大小以避免IP分段
IP分段机制并指出通常应尽可能地避免IP分段。TCP提供了避免IP分段地机制,但是UDP并没有提供相应地机制,使用UDP时如果传输地数据报大小超过了本地数据连接地MTU,那么很容易会导致IP分段。
基于UDP的应用程序通常不会知道源主机和目的主机之间的路径的MTU.一般来讲,基于UDP的应用程序会采用保守的方法来避免IP分段,即确保传输的IP数据报的大小小于IPv4的组装缓冲区的最小值576字节。(这个值很可能是要小于路径MTU的。)在这576字节中有8个字节是用于放UDP头的,另外最少需要使用20个字节来存放IP头,剩下的548字节用于存放UDP数据本身。在实践中,很多基于UDP的应用程序会选择使用一个更小的512字节来存放数据报。
58.6.3 传输控制协议(TCP)
TCP在两个端点(即应用程序)之间提供了可靠的,面向链接的、双字节流通信信道,为提供这些特性TCP必须要执行本节中描述的任务。
已连接的TCP socket
这里使用术语TCP端点来表示连接一端的内核所维护的信息。这部分信息包括链接这一端的发送和接收缓冲区以及维护的用来同步两个已连接的端点的操作的状态信息。
连接建立
在开始通信之前,TCP需要在两个端点之间建立一个通信信道。在连接建立期间,发送和接受者需要交换选项来协商通信的参数。
将数据打包成段
数据会被分解成段,每一个段都包含一个校验和,从而能够检测出端到端的传输错误。每一个段使用单个IP数据报来传输。
确认、重传以及超时
当一个TCP无措的到达目的地时,接受TCP会向发送者发送一个确认,通知他有数据发送成功了。如果一个段在到达时是存在错误的,那么这个段就会被丢弃,确认信息也不会被发送。为处理段永远不到达或者被丢弃的情况,发送者在发送每一个段时会定时开启一个定时器。如果在定时器超时之前没有收到确认,那么就会重传这个段。
由于所使用的网络以及当前的流量负载会影响传输一个段和接收其确认所需的时间,因此TCP采用了一个算法来动态的调整重传超时时间
接收TC可能不会立即发送确认。而是会等待几毫秒来观察一下是否可以将确认塞进接受者返回给发送者的响应中。这项被称为延时ACK技术的目的是能少发送一个TCP段,从而降低网络中包的数量以及降低发送和接受主机的负载。
排序
在TCP连接上传输的每一个字节都会分配到一个逻辑序号。这个数字指出了该字节在这个连接的数据流中所处的位置。当传输一个TCP分段时会在其中一个字段中包含这个段的第一个字节的序号。
在每一个段中加上一个序号有几个作用。
这个序号使得TCP分段能够以正确的顺序在目的地进行组装,然后以字节流形式传递给应用层。
由接收者返回给发送者的确认消息可以使序号来标识出收到了哪个TCP分段。
接收者可以使用序号来移除重复的分段。发生重复的原因可能是因为IP数据段重复,也可能是因为TCP自己重传算法会在一个段确认丢失或者没有按时收到时重传一个成功递出去的段。
一个流的初始序号(ISN)不是从0开始的,相反,他是通过一个算法来生成的,该算法会递增分配给后续TCP连接的ISN(为防止出现前一个连接中的分段与这个连接中的分段混淆的情况)。这个算法也使得猜测ISN变得困难起来。序号是一个32位的值,当达到最大取值时会回到0。
流量控制
流量控制防止一个快速的发送者将一个慢速的接收者压垮。要实现流量控制,接收TCP就必须要为进入的数据维护一个缓冲区。(每个TCP在连接建立阶段会通告其缓冲区的大小。)当从发送TCP端接收到数据时会将数据累计在这个缓冲区中,当应用程序读取数据时会从缓冲区中删除数据。在每个确认中,接受者会通知发送者其进入数据缓冲区的可用空间(即发送者可以发送多少字节)。TCP流量控制算法采用了所谓的滑动窗口算法,他允许包含总共N字节(提供窗口的大小)的未确认段同时在发送者和接收者之间传输。如果接收TCP的进入数据缓冲区完全被充满了,那么窗口就会关闭,发送TCP 就会停止传输数据。
拥塞控制:慢启动和拥塞避免算法
TCP的拥塞控制算法被设计用来防止快速的发送者压垮整个网络。如果一个发送TCP发送包的速度要快于一个中间路由器转发的速度,那么该路由器就会开始丢包。
两个场景:
1、 在连接建立之后:此时发送者可以立即向网络中诸如尽可能多的分段,只有接受者公告的窗口大小允许即可。
2、 当拥塞被检测到时:如果发送TCP检测到发生了拥塞,那么他就必须要降低其传输速率。
TCP的拥塞控制策略组合采用了两种算法:慢启动和拥塞避免。
慢启动算法会是发送TCP在一开始的时候以低速传输分段,但同时允许它以指数级的速度提高其速率。只要这些分段都得到接收TCP的确认。
慢启动能够防止一个快速的TCP发送者压垮整个网络。但是如果不加限制的话,慢启动在传输速率上的指数级增长意味着发送者在短时间内就会压垮整个网络。
TCP的拥塞避免算法用来防止这种情况的发生,它为速率的增长安排了一个管理实体。
拥塞避免之后,在连接刚建立时,发送TCP会使用一个较小的拥塞窗口,它会限制所能传输的未确认的数据数量。当发送者从对等TCP处接收到确认时,拥塞窗口在一开始时会呈现指数级增长。但一旦拥塞窗口增长到一个被认为时接近网络传输容量的阈值时,其增长的速度就会变成线性,而不是指数级的。
慢启动和拥塞避免算法组合,发送者可快速的将传输速度提升至网络的可用容量,并且不会超出该容量。作用是允许数据传输快速的到达一个平衡状态,及发送者传输包的速率与它从接收者处接收确认的速率一致。
58.8 总结
原文链接:https://blog.csdn.net/u010783439/article/details/130470737