TCP-IP协议
1. HTTP协议
超文本传输协议————应用层协议(提供支持的下层协议为TCP)
应用层:进程与进程间的通信
例如如下URL:
http://www.someSchool.edu/someDepartment/picture.gif
- www.someSchool.edu:主机名
- /someDepartment/picture.gif:路径名
HTTP协议定义了:
- 客户端如何向服务器请求页面
- 服务器如何将页面传送给客户端
非持久连接【non-persistent connections】
现在我们考虑:
当用户点击一个超链接后会发生什么?
- 首先是建立TCP连接的三次握手【three-way handshake】
- 在第三次握手的时候,客户端会将HTTP请求与第三次的握手(确认)一起发送出去
- 服务器收到请求信息,将对应的资源发送到客户端
综上,在非持久连接【non-persistent connections】的HTTP请求中
需要的总时间 = 两个RTT时间 + 传送文件需要的时间
持久连接【persistent connections】
可以看见,非持久连接有一些缺点:
- 每一次的请求都需要建立一次TCP连接,这会给web服务器带来巨大负担(同时可能有数百个客户端发送请求)
- 如上图所示,每一次的请求响应过程需要花费两个RTT时间
因此,HTTP 1.1 支持了持久连接
特别地,当TCP连接在一段特定的时间(用户设定值)不再使用,HTTP服务器将会关闭链接
实现了背靠背的传输【back-to-back】
HTTP数据格式
1. 请求消息
GET /somedir/page.html HTTP/1.1 Host: www.someschool.eduConnection: closeUser-agent: Mozilla/5.0Accept-language: fr
请求行【request lines】,包含了三部分:方法、资源URL、HTTP版本
首部行包括了:
- 第二行———主机名【host】
- 第三行———close表示传送数据后就断开连接
- 第四行———用户中介,也就是用的什么Browser(对于不同类型的浏览器,服务器可能会发送不同的资源信息)
- 最后一行———接受语言,标头只是HTTP中可用的许多内容协商标头之一
注意:
但用户使用POST方法的时候,才会填充entity body部分(里面的内容就是用户在表单提交的数据);
当用户使用GET方法的时候,请求的数据会跟在URL后面(有长度限制)
例如:if a form uses the GET method, has two fields, and the inputs to the twofields are monkeys and bananas, then the URL will have the structure “www,somesite.com/animalsearch?monkeys&bananas” In your day-to-day Web surfing, you have probably noticed extended URLs of this sort.
2. 响应消息
HTTP/1.1 200 OKConnection: closeDate: Tue, 18 Aug 2015 15:44:04 GMTServer: Apache/2.2.3 (CentOS)Last-Modified: Tue, 18 Aug 2015 15:11:03 GMTContent-Length: 6821Content-Type: text/html(data data data data data …)
状态行,包括三部分:版本号、状态码、相应状态消息
首部行———包括了
- Connection
- Date,服务器从文件系统获取资源,将资源放入响应消息并发送的的时间
- Server,服务器名称
- Last-Modified,表明了请求的对象创建或上一次修改的时间
- Content-Length,字节长度
- Context-Type,文本类型
常见的状态码:
- 200 OK
- 301 Moved Permently
- 400 Bad Request
- 404 Not Found
- 505 HTTP Version Not Supported
用户-服务器的交互:cookies
由于HTTP协议是无状态【stateless】的,所以服务器没法确认用户的身份
因此,我们引入了cookies(允许网站跟踪用户身份)(是一种会话【session】跟踪技术)
cookie技术有四个组成部分:
- cookie首部包含在HTTP响应消息中
- cookie首部包含在HTTP请求消息中
- 保留在用户终端系统上并由用户浏览器管理的cookie文件
- 网站上的后端数据库
例如:
假设Susan总是通过家用PC使用Internet Explorer来访问Web,她是第一次与Amazon.com联系。 让我们假设她过去已经访问过eBay网站。 当请求进入Amazon Web服务器时,服务器将创建一个唯一的标识号,并在其后端数据库中创建一个由该标识号索引的条目。 然后,Amazon Web服务器响应Susan的浏览器,在HTTP响应中包括一个Set-cookie:标头,其中包含标识号。例如,标题行可能是:Set-cookie:1678。当Susan的浏览器收到HTTP响应消息时,它会看到Set-cookie:标头。 然后,浏览器将一行添加到它管理的特殊cookie文件。 该行包括服务器的主机名和Set-cookie:标头中的标识号。 请注意,由于Susan过去曾访问过该站点,因此该cookie文件已经具有eBay条目。 随着Susan继续浏览亚马逊站点,每次她请求一个网页时,她的浏览器都会查询她的cookie文件,提取该站点的标识号,并放置一个cookie标题行,在HTTP请求中包含标识号。 具体来说,她对Amazon服务器的每个HTTP请求都包括标题行:Cookie:1678Amazon服务器就可以跟踪Susan在Amazon站点上的活动。 尽管亚马逊网站不一定知道Susan的名字,但它确切知道用户1678访问过哪些页面,以什么顺序,在什么时间!亚马逊使用cookie来提供购物车服务-亚马逊可以维护Susan打算购买的所有商品的清单,以便她可以在会议结束时集体付款。如果Susan一周后返回亚马逊的网站,例如,她的浏览器将继续在请求消息中添加标题行Cookie:1678。 亚马逊还根据她过去在亚马逊上访问过的网页向Susan推荐产品。 如果Susan也向亚马逊注册(提供全名,电子邮件地址,邮政地址和信用卡信息),那么Amazon可以将此信息包括在其数据库中,从而将Susan的名字与她的识别号(以及她所有的页面)相关联。 过去曾访问过该网站!)。 这就是Amazon和其他电子商务网站提供“一键式购物”的方式,当Susan在后续访问期间选择购买商品时,她无需重新输入姓名,信用卡号或地址
【注意】:
- cookie具有不可跨域名性
- cookie的有效期是需要设置的
- cookies的存储类似于Map集合(键-值对)
网页缓存【Web Caching】
网页缓存,又称为代理服务器【proxy server】
网页缓存有它自己的存储空间,并且保存了最近请求的对象(访问速度会更快)
下面我们观察一下工作过程:
假设请求的对象为http://www.someschool.edu/campus.gif
- 浏览器首先和Web缓存建立TCP连接,并发送HTTP请求
- Web缓存检查是否已经在本地存储上了,如果在直接返回
- 如果不在,则与源服务器建立TCP连接,请求对象
- 当Web缓存接收到对象后,会copy一份到本地存储中,并发送给浏览器
从上述过程中我们可以看出,有某种情况下,web缓存既是服务器,又是客户
通常情况下,Web缓存由ISP(网络服务提供商)购买和安装的
WEB缓存在互联网上发展有两大原因:
- 可以大大减少客户请求的响应时间。尤其是如果客户端和原始服务器之间的瓶颈带宽远小于客户端和缓存之间的瓶颈带宽
- 减少机构访问因特网的流量。减少流量,因而节省成本,从而提升整个互联网应用的性能
2. UDP协议
面向无连接【conectless】
首部8字节
外加12字节的伪首部
【注】:
这里的伪首部并不是真正意义上的首部,只是在计算校验和的时候才加上去的
UDP是面向报文【packet】的
3. TCP协议
可靠数据传输:(左)服务模型、(右)服务实现
可以看见,在传输层实现的是端到端之间的逻辑通路
面向连接
当一个进程向另一个进程发送数据的时候
需要先经过**“三次握手”**【three-way handshake】建立连接
这种看连接并非端到端【end-to-end】的TDM【时分复用】/FDM【频分复用】,也不是一条虚电路
并且向下层隐藏了连接
网络层只能看见数据报,而看不到连接
端到端逻辑链接
TCP连接 包含了:
- 缓沖区【buffers】
- 变量【variables】
- socket连接
但是,在主机之间的 路由器【router】、交换机【switchs】、转发器【repeaters】却 没有为连接缓存或者变量
首部格式
20个字节的固定首部
TCP协议将数据视为————无结构的、有序的字节流【stream of bytes】
1. 序号【sequence number】
序号为:段中第一个字节的字节流号码
例如上图所示,
一共传输50字节的数据,而单次最大传输为100字节,因此
- 第一个报文段的序号:0
- 第二个:1000
- 第三个:2000
- ……
2. 确认号【acknowledgment numbers】
如果A接受到从B来的 0-535字节的数据,那么希望接下来接收到序号536的数据
这时,A就会向B发送确认号536
(TCP仅确认流中第一个丢失的字节的序号)
【注】
- 20个字节的TCP首部,20个字节的IP首部,又由于MAC帧数据部分的最大长度为1500字节,因此TCP数据长度最大为1460字节
3. SYN同步码
该标志仅在三次握手建立TCP连接时有效
它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接初始端(一般是客户端)的初始序列编号
在这里,可以把 TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器
通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。
可靠传输
使用单一的超时计时器
保证数据流是无损坏、无间隔、无冗余、按顺序的
如上图所示,第一种情况:
在定时器时间内返回的确认报文丢失,这时候A只能重新发送序号为92的报文
如上图所示,第二种情况:
A连续发送了两个报文
可是,序号92和100的确认报文都超时了,也就意味着需要重新发送
但是,只要第二个报文的ACK在新的定时器内到达B,那么就不需要再重新传第二个报文了
如上图所示,第三种情况:
同第二种情况一样,A连续向B发送了两段报文
可是第一个报文的确认报文丢失了
但是,只要在序列号92的定时器时间范围内,收到了确认号120的报文,甚至不需要重发序号92的报文
因此,A也就知道B收到了序号到119为止的所有报文,而不用再重新传送
快重传
当出现一个报文序号大于当前应该预期的报文序号时
说明检测到了一个缺口【gap】————丢失了中间的某个报文段**(由于TCP保证数据的有序性,因此是不允许这种情况出现的)**
那么这个时候,接收方B需要重新传送三次想到的序号的报文的ACK给A
A就会重新传输序列号为ACK的报文
流量控制
通过发送方维护一个接收窗口【receive window】
这用于通知发送方————接收方还有多少可用的缓存空间
因为TCP协议是全双工的【full-duplex】,因此每一端的发送方都需要维护一个接收窗口
【扩展阅读】
单工、半双工、全双工
-
单工
1、数据只在一个方向上传输,不能实现双方通信。
2、栗子:电视、广播。
-
半双工
1、允许数据在两个方向上传输,但是同一时间数据只能在一个方向上传输,其实际上是切换的单工。
2、栗子:对讲机。
-
全双工
1、允许数据在两个方向上同时传输。
2、栗子:手机通话。
另外,有以下的定义:
- RcvBuffer:缓冲区大小
- LastByteRead :缓冲区读出的最后一个字节序号
- LastByteRcvd :缓存中的最后一个字节序号
- 由于TCP不允许缓冲区溢出,所以有公式:$LastByteRcvd – LastByteRead RcvBuffer $
- 接收窗口rwnd:$rwnd = RcvBuffer – [LastByteRcvd – LastByteRead] $
由于空闲空间随时间改变,所以rwnd窗口也是动态变化的
TCP连接管理
建立连接
我们来看一看三次握手到底是怎么实现的!
- 客户端向服务端发送一个特殊的TCP报文(不包含任何应用层数据),同步码SYN=1,然后随机选择一个初始序号
- 服务端接收到报文,提取SYN,为该TCP连接分配缓存和变量,并向客户端发送允许连接的确认报文段(同时不包含应用层数据),SYN = 1,ACK = 接受的seq+1,最后服务端选择一个初始序号
- 在收到SYNACK报文后,客户端也要给该连接分配缓存和变量,客户端会向服务端再发送一个报文段。这最后一个报文对服务器的允许连接进行了确认。因为连接已经建立了,所以SYN = 0,第三个报文可以将要发送的数据随着报文发送给服务端
【思考】
==为什么是三次握手?==而不是两次或者四次?
一句话概括,TCP连接握手,握的是啥?通信双方数据原点的序列号!
很显然,
- 4次握手————连接速度和效率会降低
- 2次握手会导致————B无法知道A已经接收到了自己的同步信号,记录初始化序列号(万一B发送给A的报文丢失了,那么A和B就B的初始化系列号就无法达成一致)
释放连接
下面观察4次握手的过程:
- 客户端发动FIN = 1,随机序列号给服务端以主动关闭连接
- 服务端接收信息,并返回确认报文,并且通知应用进程
- 一段等待后,服务端被动关闭连接,发送FIN = 1的,随机序列号的报文
- 客户端接收到后,发送确认报文给服务端
- 服务端接受到客户端发来的确认报文,正式关闭连接
- 客户端再发送完确认报文一段时间后关闭连接
TCP状态【states】
扩展阅读
拥塞控制
TCP拥塞控制使用了————端到端【end-to-end】的拥塞控制方法
当发送方察觉没有拥堵时,会加大传输速率;
若发送方察觉到有拥堵时,会减少传输速率
但是,这引出了三个值得思考的问题:
- 发送方如何限制传输通道上的速率?
- 发送方如何察觉到拥塞?
- 发送方应该使用什么算法来改变传输速率?
下面对于三个问题的解决思路:
- 利用调整拥塞窗口【cwnd】大小控制发送的数据量
- 利用ACK报文来感知拥塞,如果ACK到达的越快,那么cwnd增长的越快
- TCP拥塞控制算法(慢开始—》拥塞避免—》快恢复)
1. 慢开始【slow start】
一开始,cwnd初始化为1
当收到ACK后,cwnd扩大为2
如此指数级往复增长
那么问题来了,什么指数级增长停止?
————我们设置第二个变量:ssthresh【shorthand for “slow start threshold” 】(慢启动阈值的简写)
当cwnd ≥ ssthresh时,我们说慢开始就结束了,接下来进入拥塞避免
【注】
- 还有另一种情况,当出现三次重复ACK报文时,TCP会进行快重传,然后进入快恢复阶段
2. 拥塞避免【Congestion Avoidance 】
拥塞窗口:每次cwnd + 1,也就是拥塞窗口递增
接下来会出现两种情况:
-
超时:这时ssthresh = cwnd/2,cwnd = 1
那么这个时候,慢开始的阈值会设为拥塞窗口的一半,拥塞窗口设置为1,重新进入慢开始阶段
-
三次重复ACK:$ssthresh = cwnd/2, cwnd=ssthresh+3•MSS $
这个时候说明只是丢失了部分报文,并不是网络阻塞,那么将慢开始的阈值会设为拥塞窗口的一半,拥塞窗口设置为慢开始阈值,直接进入拥塞避免阶段
【注】为什么要加3 * MSS【最大报文长度】 ?(暂时不知道)
3. 快恢复【fast recovery】
4. IP协议
网络层实现了 主机——主机【host-to-host】之间的通信
两个关键术语【term】:
- forwarding:发送。从输入链路接口到输出链路接口传送IP数据包的本地路由器行为(由硬件支持,通常只需要几纳秒)
- routing:路由。决定IP数据包传送的端到端的路径(由软件实现,通常需要几秒)。路由就像从一个城市到另一个城市规划路线的过程。
IP层仅提供一种服务————尽最大努力交付【best-effort service】
路由器里有什么
input port 、switch fabric 、output port由硬件支持
一组输入端口
一组输出端口
交换结构
路由器从功能上可以划分为:
- 路由选择
- 分组转发
IP数据包格式
Every networking students needs to see it, absorb it, and master it
-
版本号:4位。
-
头部长度:4位决定ip数据报首部的长度,标准为20个字节
-
服务类型
-
数据长度:16位长度,最大可以有65535字节。但是,数据报数据长度很少有超过1500字节。
【注】
MAC帧的最大传输单元为1500字节,因此除去20字节的IP数据头部,IP报数据部分最多1480字节,这也是为什么IP数据报分片的原因
-
标志位:段偏移
-
TTL生存时间:IP数据包传送每经过一个路由器,TTL减1,但TTL = 0时,路由器将会丢弃该数据报
-
上层协议:是TCP/UDP
-
首部校验和
-
源ip地址
-
目的ip地址
-
选项option
-
数据
DHCP【dynamic host configuration protocol】的过程
- DHCP发现:客户端发送UDP报文
- DHCP提供:服务器响应一个提供消息,广播发送给子网的所有主机 (思考为什么是广播发送),发送一个ip地址(附带有效期)
- DHCP请求:客户端发送请求消息,等待响应配置参数
- DHCP确认:服务器确认请求的配置参数
NAT地址翻译
在私有地址和全局地址之间转换的协议
并且能有效避免来自外部网络的攻击,有助于隐藏网络内部的计算机
私有地址使用在局域网内部,它是不能在互联网上使用的
- 私有网络的三个地址块
- A 类:10.0.0.0~10.255.255.255
- B 类:172.16.0.0~172.31.255.255
- C 类:192.168.0.0~192.168.255.255
【注】
为什么要这么麻烦使用私有地址呢?直接用 全局地址不就完了?
这是为了解决IPv4不够用的情况
可以观察上图,简单理解NAT协议执行的流程
- 首先主机10.0.0.1向目的ip地址128.119.40.186:80发送ip报文
- NAT路由器查表,得知10.0.0.1:3345的原始ip地址为138.76.29.7:5001,将ip报文的源【source】变更
- 从公共网络中收到ip报文,还需要再经过NAT路由器,将目的ip地址转换成私有地址
路由算法【routing algorithm】
1 Link-State 【LS】路由算法
使用dijkstra算法
2 Distance-Vector【DV】路由算法
异步的,分布式的
每个节点各自保存一些信息
自我决策的算法
去中心化的算法
使用Bellman-Ford算法(解决负权重环)
开放式最短路径优先【OSPF】
是一个内部网关协议
边界网关协议【BGP】
运行于 TCP 上的一种自治系统的路由协议
路由选择算法【route-selection algorithm】
SDN网络
SDN字面意思是软件定义网络
其试图摆脱硬件对网络架构的限制,这样便可以像升级、安装软件一样对网络进行修改,便于更多的APP(应用程序)能够快速部署到网络上。
ICMP网络控制报文协议
在IP通信中,经常有数据包到达不了对方的情况。原因是,在通信途中的某处的一个路由器由于不能处理所有的数据包,就将数据包一个一个丢弃了。或者,虽然到达了对方,但是由于搞错了端口号,服务器软件可能不能接受它。这时,在错误发生的现场,为了联络而飞过来的信鸽就是ICMP 报文。在IP 网络上,由于数据包被丢弃等原因,为了控制将必要的信息传递给发信方。ICMP 协议是为了辅助IP 协议,交换各种各样的控制信息而被制造出来的。
制定万维网规格的IETF 在1981 年将RFC7922作为ICMP 的基本规格整理出来了。那个RFC792 的开头部分里写着“ICMP 是IP 的不可缺少的部分,所有的IP 软件必须实现ICMP协议。也是,ICMP 是为了分担IP 一部分功能而被制定出来的。
ICMP最普遍的用是————差错报告【error reporting】
在某些时候,IP路由器找不到HTTP请求中指定的主机的路径,路由器会创建并传送ICMP报文给你的主机以报告错误
ICMP被认为是IP的一部分,可是它位于IP之上,因此,IP数据报携带了ICMP的消息
最著名的ping命令就是发送icmp消息给目标主机的
The well-known ping program sends an ICMP type 8 code 0 message to the specified hostThe destination host, seeing the echo request, sends back a type 0 code 0 ICMP echo reply
简单网络管理协议【SNMP】
最常见的作用是:
SNMP管理服务器发送请求给SNMP代理【agent】,当代理接受请求后,会做出某些行为或者响应请求
一套完整的SNMP系统主要包括:管理信息库【MIB】、管理信息结构【SMI】和SNMP报文协议