计算机网络层次与对应协议的理解
- 应用层
- 对数据的具体应用 HTTP/DNS/FTP/NFS/SMTP/POP3/IMAP/SNMP等
- 表示层
- 对数据进行格式转换,加解密,解压缩等(没有协议)
- 会话层
- 会话管理,控制应用之间的通信,比如访问验证 (没有协议)
- 传输层
- 通信双方数据传输。TCP面向连接可靠/顺序/流量控制/全双工/多路复用;UDP非面向连接不可靠,但传输经济
- 网络层
- 路由选择合适的链路。IP/OSPF。IP属于外部网络,OSPF是内部网络(AS-自治系统)
- 数据链路层
- 定义数据帧在链路上的传输无差错。封装成帧->透明传输->差错检测
- 物理层
- 规定传输媒体(介质)的接口相关的特性。规定机械规格和在媒体上的具体传输方式(电流/光等),使用各种办法传输bit
- 机械特性 形状、尺寸、引脚数等规格
- 电气特性 电缆等线路上的电压范围等
- 功能特性 某一电压表示的含义
- 过程特性 指定各种可能事件出现顺序
- 规定传输媒体(介质)的接口相关的特性。规定机械规格和在媒体上的具体传输方式(电流/光等),使用各种办法传输bit
1. 物理层
物理层主要跟电气相关。比如,通信信号有模拟信号,数字信号;使用电缆或者光纤等就不做多介绍了
2. 数据链路
数据链路在信道中通讯有两种:点对点(PPP)和广播信道。
2.1 点对点的信道的数据链路层
点对点的数据链路层有3个基本问题:封装成帧、透明传输和差错检测
2.1.1 封装成帧
数据链路层把网络层的IP数据头尾包封装为帧,并且传递给物理层传输bit。帧的长度是有最大限制的,不能超过。同时帧中的数据部分尽可能大于首部和尾部,提高传输效率。
2.1.2 透明传输
由于帧的首部(00000001)和尾部(00000100)使用1字节来做定界符(非可打印字符),如果数据部分出现了怎么办?比如二进制数据。
为了保证任何数据都能传输,因此要做到透明传输。这个透明是指 A网络层 --> B网络层,这个传输过程中接受的是原样数据。A网络层发什么,B的数据链路层就给B的网络层传递什么。
那么,如果是含有帧定界符的数据内容呢?那就要做转义,前面添加1字节(16进制1B)。
2.1.3 错误检测
这个是数据链路层最重要的部分。因为每一个层次都进行一次数据封装;也会透明传输,因为通讯双方同层次之间的通讯并不需要知道互相的下一层次做了些什么处理,也就说同层次通讯是透明传输的。错误检测是数据链路层相对其他层次不一样的。
错误检测,差错是指比特差错。目前采用的是循环冗余检验
CRC。数据需要分组,每组K个比特,CRC运算就是在这K个比特后面添加n位冗余码
,然后构成一个帧(k+n)发送。
模2运算
是CRC的核心部分。冗余码的得到方法是;M 2^n ==> M << n ==> M的二进制加上n个0,然后把(k+n)位模2除以P(n+1位)为,其中商是Q,余数是R(n位)。那么这个R就是帧检验码FCS。最后就是(2^n M + FCS)
需要有模2运算的基础,该运算是有加减乘除的。其实跟二进制的四则运算一样,不同的是不管进位,错位,只管当前对应位的运算。我们知道乘法和除法都是基于加减法的,因为通过竖式可以知道,最终乘法是相加,除法是相减。差异就在这加减法上,没有进位。
模2加法:
1001
1101
——
0100
模2减法:
1100
1101
——
0001
可以看出,模2加减法是一样的,也是跟异或运算一样的
接收端如何检验?把接收的(k+n)对P模2除法得出的余数R。如果是0,那就说明无差错。
P这个数的选取很讲究的,通过P(x)得到。比如,用:
P(X) = = X^2 + X^1 + 1
表示1101。其中还有CRC16,CRC32等
注意:数据链路只是保证数据无差错,不能保证数据是否重复,是否顺序,是否丢失。
2.2 使用广播的数据链路层
广播是以太网(一种局域网)上的传播方式。简单理解就是通过一条总线连接在一起的网络,一台机器发送数据,其他机器都能接收到。机器针对不是发给自己的机器机型丢弃(所以说局域网不安全,可以不丢弃的呀)。以太网使用曼切斯特编码。以太网最大问题就是竞争总线,在传输之前都检测是否被占用,如果被占用需要等待一定时间再次传输。
3. 网络层
主要的协议有IP协议/ICMP协议/ARP/RARP。该层的传输通过封装成IP数据报。ICMP报文也是使用IP数据报的,但是一般认为同属于网络层。
3.1 常用的3种IP地址
A类:
- 网络号1字节,首位0固定,剩余7位。2^7 - 2可用,因为网络号全零表示本网络。恰好全1则是127是本地回环地址。
- 主机号3字节。2^24 - 2可用。全零可以指定所在网络。5.6.7.8中5.0.0.0指定所在网络;全1 => 5.255.255.255表示所在网络所有主机
- IP地址空间占50%
B类: - 网络号2字节,10固定。地址空间占25%
C类: - 网络号3字节,110固定。地址空间占12.5%
3.2 IP地址与硬件地址(MAC地址)
在Ip层只能看到IP数据报,数据报中的源地址与目标地址始终是Ip1与Ip2,中间经过的两个路由只是转发。路由器根据地址IP找到下一个同网络的路由。对于同网络如何传输过去?
在数据链路层中的Mac帧中源地址和目的地址一直改变。这个是局域网的数据传输方式
出现两个问题:
- 路由怎么知道下一个路由的Mac地址,也就是IP与物理地址映射表如何得出
- 路由表怎么得出。路由器互相交换信息得到。
3.2.1 地址解析ARP与逆地址解析RARP
ARP:知道IP如何找到物理地址
RARP:知道物理地址怎么知道IP
ARP:
网络层使用IP,但是实际在链路传输数据帧还是必须使用网络物理地址。每一个主机都有一个ARP高级缓存(有过期时间),存放本地的机器IP与物理地址映射表。我们知道缓存就是有就用,无就重新获取。使用了一个广播的方式,比如你在群上问:
你(A):我的IP是209.0.0.5,硬件地址是00-00-C0-15-AD-18,209.0.0.6(B)主机硬件地址发我一下?
群上所有人都接收到了
B看到信息的IP是自己,就回复:我的地址是209.0.0.6,硬件地址是啥啥..(注意这里是单播,指定源地址与目的地址)
- 问:为什么使用IP,然后再去ARP获得硬件地址去传输;而不是直接使用物理地址?
- 答:各式各样的网络,硬件地址很不同,不能要求全网所有都要同一种网络。因此网络层统一的IP地址可以解决这个问题。虚拟网络互联。
ARAP:这个知道物理地址,就好像你知道是谁,那就直接问他IP是什么好啦。
注意:IP数据报格式就不介绍了,比较复杂,可以看谢希仁的《计算机网络》
3.3 子网
问题是IP地址只是分3级,需要分更多怎么办
IP地址 = <网络号><子网号><主机号>
如何判断是同一个网络,而且还是同一个子网?
- A类:255.0.0.0
- B类:255.255.0.0
- C类:255.255.255.0
原理是通过与运算(AND)
划分子网之后,那么就变成子网之间传输也是需要至少一个路由器的。首先通过子网掩码判断是否该网络,如果不是则交给路由传递该相应的子网。
3.4 超网-无分类编址CIDR
3级变成2级:
IP = <网络前缀><主机号>
可以使用斜线/写法,"/"后说明网络前缀的长度:
128.14.35.7/20 说明网络前缀是前20位
还可以使用星号*:
0001101100*,星号全面的是前缀,后面是主机号可以是任意数。这种IP地址有一个问题,就是有可能会匹配多个网络:
- 大学:11010*
- 学院:11010001*
- 某系:110100010001*
这个时候,如果IP地址是110100010001111...怎么办?书哪一个网络?最长前缀匹配原则!!!
还有的问题是,怎么在路由表中更具网络前缀查询网络呢?二分查找,因为bit要么0,要么1,可以使用二叉树结构存储路由表。
3.5 ICMP网际控制报文协议
主机或者路由器报告差错情况等。差错报文与询问报文
- 差错报文 (被动接收的)
- 终点不可达 路由器或者主机(以下统称主机)不能交付数据报(交付给某主机或者主机的某个端口)会发送
- 源点抑制 主机网络阻塞就向源点发送,告知源点减慢速度
- 时间超过 TTL等于0的时候
- 参数错误 数据报首部参数不正确就发送
- 改变路由(重定向)主机接受到数据报,但是认为有更好的路由选择,则会向源点发送该报文
- 询问报文 (主动请求的)
- 回送请求和回答:就是简单的回答,测试可达性.应用层的ping程序就是使用该方法
- 时间戳请求和回答:进行时间同步和测量时间
3.6 ICMP的简单应用
ping是应用层直接应用网络层的例子,用于测试连通性。还有的就是traceroute(win是tracert),跟踪一个分组从源点到终点的路径
traceroute原理:源机器向目标机器发送IP数据报,数据报是无法交付的UDP用户数据报。第一次请求设置TTL=1,到达路由R1,TTL减1为0,这时候R1把数据报丢弃,并且向源主机发送ICMP时间超时报文。这样一直下去,找到目的主机,因为不可交付的UDP用户数据报,因此最后目的主机向源主机发送不可达的ICMP错误报告报文。
3.7 路由选择协议
- IGP,内部网关协议:AS内部的路由选择协议,比如,RIP,OSPF。
- EGP,外部网关协议:AS之间的路由选择协议,比如,BGP。
3.7.1 RIP内部网关协议
基于距离向量的路由选择协议。直接连接的网络距离定义为1,之后没经过一个路由器到达的网络,则距离加1;RIP中距离称为"跳数"。并且规定最多经过15个路由,因此距离为16认为不可达。15?可见RIP适合小型的互联网。
特点:
- 仅和相邻路由(同网络)交换信息
- 交换自身路由表信息(互相发送RIP报文)
- 固定时间交换,比如30秒
注意:新加入的路由器只是知道直接相连的距离为1,经过与其他路由交换信息就会知道本AS的路由表信息了。
3.7.2 OSPF内部网关协议
可以理解其实跟RIP的原理有点相似,但是OSPF使用分布式的链路状态协议,而不仅仅是单纯的距离,还考虑了链路的阻塞,时延,距离,带宽,费用等链路状态。
3.7.3 BGP外部网关协议
BGP - 边界网关协议。为什么不同AS不使用上面两种协议?主要一下两个原因:
- 因特网规模太大,使得AS之间路由选择非常困难
- 在因特网主干网上使用OSPF性能低,并且AS对度量的尺度不一等。
- AS之间路由选择必须考虑有关的策略。比如AS1需要经过AS3才能到AS2,此时AS3不想让AS1经过,或者需要服务费。因此AS之间路由选择需要更多选择策略。这些策略是选择较好的而不是最佳的。
原理:
每个AS至少需要一个BGP发言人-BGP边界路由器,互相通过TCP连接交换路由信息。交换的信息就是要到达某个网络需要经过一系列的AS。比如AS2,说要经过N1,需要经过AS2。AS1接受后,说经过N1,需要经过(AS1,AS2)。
4 传输层
面向连接的TCP与无连接的UDP。网络层解决了数据如何从源主机到达目标主机,那么传输层则在网络层的基础上控制具体的传输策略。比如TCP可靠服务(对丢失/重复/失序进行处理)、流量控制、阻塞控制
4.1 TCP 传输控制协议
了解TCP的报文头,并且根据报文头来学习TCP协议是非常好的方法,能够更好的理解TCP报文头和TCP的功能。其实不管是哪一个协议也是如此的。
- 面向连接。3次握手建立连接,4次握手断开连接。
- 无差错、不丢失、不重复、并且按序到达(超时重传,接收和发送窗口,阻塞控制)
- 只能有两个端点,一对一
- 全双工通信
- 面向字节流。应用层交下来的的数据被看成字节流。应用交付下一层的数据大小是无限制的,就像是一个流水线一样。只要写入的数据装满缓冲区或者关闭写操作就发送一个报文段。
其实最重要的是TCP如何实现可靠传输?
- 出现差错就丢弃
- 每一个分组,接收方都需要回复
ACK
确认。否则发送方会一直发(当然等待一段往返时间RTT)。 - 重复则丢弃,并且回复
ACK
,告述发送方不要再再发了 - 按序到达。发送方会有发送窗口,会按顺序移动窗口进行发送。
如何实现流量控制?
- 接收方有接收窗口,如果来不及接收和处理数据会告诉发送方缩小发送窗口,减缓速率,实现流量控制
连接的3次握手:
- 问:ACK=1是确认报文的意思,那么对哪一个报文进行确认?
- 答:注意到
seq
和ack
了吗。seq=x
表示该报文的序列号x
可以识别该报文。服务端回复中的ack=x+1
,则表示目前x
以及以前的都接受成功,可以发送x+1
了!这就起到了针对某一个报文就行发送ACK
确认。
释放连接的4次握手:
- 问:为什么连接需要3次,但是释放需要4次?
- 答:因为在建立连接的时候服务端把
ACK
和SYN
一起发送了,因为建立连接服务端已经准备好了。而在释放连接的时候;客户端申请释放的时候,服务端接收到申请,但是还没有准备好,比如最后一个分组的ACK还没有接收到,这个时候就先对客户端回复ACK;等到准备就绪才回复FIN。就这样多了一次握手。
半关闭状态:
TCP
是半双工的。因此允许双方独立的关闭。如果一方结束发送数据给对方,那么可以告诉对方完成数据发送,但是仍然可以接收对方发来的数据,直到对方也结束数据发送以关闭连接。下图中系统调用read
返回0的时候,就是对方要关闭连接的时候。
TCP状态转移 netstat命令
TCP
从建立到关闭,通讯双方的状态,具体如下图。值得注意的是,关闭连接可以分为主动关闭和被动关闭,这两个的状态转移是不一样的。被动的很好理解,主动的就稍微复杂些。比如FIN_WAIT_1
(主动发送FIN之后)/FIN_WAIT_2
(只是收到ACK)/CLOSING
(发送了FIN
还没收ACK
后收到对方发的FIN
,那就一起关闭吧)/TIME_WAIT
(等待关闭,等待2个报文最大生存时间,看看对方是否接收到该给它的ACK
,毕竟不能不辞而别)
主动关闭中必然会存在的状态有两个:FIN_WAIT
/TIME_WAIT
。并且从FIN_WAIT
到TIME_WAIT
必须接收到一个ACK
和一个FIN
,可以同时接收,也可以任意先后。因此会有3种可能:
ACK
和FIN
同时接收并且对此发确认ACK
-->TIME_WAITACK
先收到-->FIN_WAIT_2(等待FIN
后发ACK
)-->TIME_WAITFIN
先到(这个时候几乎是双方同时要求关闭,对对方的FIN
进行确认ACK
)-->CLOSING(等待对方对我方FIN
的ACK
)-->TIME_WAIT
TIME_WAIT的作用
- 可靠地终止TCP连接
- 保证迟来的TCP报文有足够时间被识别并且丢弃
- 一个TCP端口不能呗同事打开,TCP连接处于
TIME_WAIT
状态的时候,我们无法占用该端口并且重新打开连接。假设TIME_WAIT
不存在,那么我们可以重新建立一个新的TCP连接(IP与端口一致),那么新的连接可能会接收到原来连接的报文段,这明显是不正确的。 - 为什么是2MSL报文最大生存时间?因为经过这段时间的迟到的报文会直接被路由器丢弃,可以安全的建立连接
- 那能不能马上建立连接?客户端建立连接使用的是随机端口(能保证不是一样的端口),因此可以马上见建立。对于服务端,可以通过socket选项SO_REUSEADDR来强制启动(当然后果你是需要知道的啦)
- 一个TCP端口不能呗同事打开,TCP连接处于
复位报文
啥是复位报文?TCP报文的报文头中有标记位,其中
RST
告诉对方要关闭或者重新连接。在某些特殊情况写会发送此报文。
1.访问不存在的端口
其实如果端口还在背占用的时候,比如在TIME_WAIT状态的时候也是会发复位报文。
# 在一个终端中使用tcpdump抓包
# Flags [S] 说明是一个SYN同步报文,要求建立TCP连接
# Flags [R.] 说明是一个有RST复位报文,要求关闭连接,并且确认收到SYN报文。注意到win 0,这个说明不要回应这个复位报文
> sudo tcpdump -nt -i lo0 port 54321
IP 127.0.0.1.49953 > 127.0.0.1.54321: Flags [S], seq 1166333184, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 930108577 ecr 0,sackOK,eol], length 0
IP 127.0.0.1.54321 > 127.0.0.1.49953: Flags [R.], seq 0, ack 1166333185, win 0, length 0
# 另一个输入
> telnet 127.0.0.1 54321
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host
2.异常终止连接
TCP提供了异常终止连接的方法。通过socket选项SO_LINGER来主动发送复位报文
3.处理半打开连接
就是通讯一方仍然持有连接,但是另一方已经断开了。比如服务器要重启,发送关闭连接报文,但是客户端由于网络原因(比如断网)接收不到报文,当服务器重启完毕和客户端重新连接上网络的时候,服务端已经是没有这个连接,但是客户端还是保持这个连接的。如果客户端给服务端发送数据,那么服务端就会给客户端发送复位报文
TCP交互数据流
TCP报文段按照大小可以分为两种:交互数据和成块数据。交互数据是比较小的,包含较少字节,比如telnet和ssh。成块数据大小经常是TCP报文段最大长度。
比如,客户端使用telnet访问服务端。在传递过程中的就是交互数据流。客户端发送的ACK
是不包含数据的(马上对接收的报文段确认);相反服务端的ACK
报文段一般都会带有数据的,一方面可以确认客户端发来的报文段,另一方面可以就其请求做出响应返回数据。服务端这种处理是延迟确认
;就是先不急着发送确认,而是等服务端是否有数据要发送,如果有带上一起发就好。这样的优点就是减少传输微小的报文段传输。那么客户端怎么不这么做?等了,但是等不到啊,因为telnet来访问的话,需要用户敲键盘啊,太慢了。
TCP成块数据流
成块数据流,很好的例子就是使用
ftp
下载大文件。
请求过程很可能是:
- 客户端请求下载文件
- 服务端发送大报文段1
- 服务端发送大报文段2
- 服务端发送大报文段3
- 服务端发送大报文段4
- 客户端
ACK
确认接收报文段1到4
这种情况,发送方连续发送多个报文段,接收方可以一次性进行确认。
带外数据
带外(Out Of Band, OOB)数据。用于迅速告诉对方,本端发生的重要事件。因此会比普通数据(带内数据)的优先级要高,不放缓冲区,不排队,立即发送,立即读取。TCP中可以使用
紧急指针标志
来实现。
4.2 UDP 用户数据报协议
- 无连接
- 尽大可能交付
- 面向报文。应用层往下发的报文,直接加上首部就交给网络层,UDP一次性交付一个完整报文给网络层。应用给多大,我发送多大。具体分片由IP协议处理
- 支持一对一,一对多,多对多
- 没有阻塞控制。就是网络的阻塞不会导致主机发送速率降低。
5 应用层
HTTP/DNS/FTP等。待补充
5.1 HTTP 超文本传输协议
求是就是通过TCP连接,两台主机按照HTTP协议规定的文本格式进行互相通信。比如第一行是什么,第二行是什么等等。完全可以使用变成语言通过TCP连接来实现一个简单的HTTP请求。
5.2 DNS域名系统
使用UDP协议。就是根据域名查询对应的IP。比如通过浏览器请求某个网站:
- 首先是浏览器的DNS缓存
- 系统的DNS缓存
- 系统的hosts
- 请求DNS服务器
6 Linux或者Mac上的小应用
为了加深理解,这里推荐一些命令
6.1 查看ARP高速缓存
用于查看和设置本地的ARP高速缓存的。比如想看ARP请求过程,这个时候就需要先删除缓存,重新请求一次啦。
# 删除
arp -d 192.168.0.1
# 设置
arp -s IP地址 MAC地址
# 查看
arp -a
6.2 tcpdump 查看ARP通讯过程
tcpdump 是一个抓包命令。有了抓包,那怎么触发ARP请求呢?只要使用IP协议都能触达ARP。可以使用telnet简历TCP前就需要进行ARP请求;或者使用ping命令(不过要注意的是,ARP之后就会发ICMP报文)
# -i 指定 interface 网卡
> sudo tcpdump -i eth0
11:22:18.656009 ARP, Request who-has 192.168.43.1 tell lizhichengdembp, length 28
11:22:18.659657 ARP, Reply 192.168.43.1 is-at a6:44:d1:dd:ed:35 (oui Unknown), length 28
# 还可以使用表达式
> sudo tcpdump -i en0 '(dst 192.168.43.1 and src 192.168.43.184)or(dst 192.168.43.184 and src 192.168.43.1)'
6.2 Linux访问DNS服务
6.2.1 host 命令
# 查询 www.baidu.com 的A记录
> host -t A www.baidu.com
6.2.2 tcpdump查看DNS通许过程
# 在一个终端输入
> sudo tcpdump -i en0 -nt -s 500 port domain
IP 192.168.43.184.63356 > 192.168.43.1.53: 48260+ A? www.baidu.com. (31)
IP 192.168.43.1.53 > 192.168.43.184.63356: 48260 3/5/5 CNAME www.a.shifen.com., A 183.232.231.173, A 183.232.231.172 (260)
# 在另一个终端中
> host -t A www.baidu.com
www.baidu.com is an alias for www.a.shifen.com.
www.a.shifen.com has address 183.232.231.173
www.a.shifen.com has address 183.232.231.172
6.3 查看报文二进制
# tcpdump的-x选项可以做到
> sudo tcpdump -ntx -i lo0
然后使用 ping或者telnet本地
6.4 IP分片与tcpdump只抓取ICMP
# 只抓取ICMP 注意offset偏移,第二个数据报的offset是第一个数据报的length;id是一样的;flags[+]说明后面还有后续分片,flags[none]表示后续买有其他分片了。这里的flag是ipv4报文头部中3位标志
> sudo tcpdump -ntv -i lo0 icmp
IP (tos 0x0, ttl 64, id 65515, offset 0, flags [+], proto ICMP (1), length 1500)
192.168.43.184 > 192.168.43.1: ICMP echo request, id 14342, seq 0, length 1480
IP (tos 0x0, ttl 64, id 65515, offset 1480, flags [none], proto ICMP (1), length 21)
192.168.43.184 > 192.168.43.1: ip-proto-1
# 指定长度 让其炒股单个IP数据报限制长度,使其分片
> ping 127.0.0.1 -s 1473 -c 1
本文属于个人读书笔记,不正确的欢迎指正。后续会根据理解的加深而继续完善
7. 其他
- 也许有人回想起
WebSocket
。这个与socket
又有什么关系呢?WebSocket
只是一个长的Http连接,一般用于聊天室
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: