应用层

体系结构

进程通信

两个端系统之间的通信,本质是两个进程之间的通信,进程通过使用操作系统提供的接口与另一个端系统上的进程进行通信,这个接口是套接字

套接字 =(IP,端口号)

应用程序能控制的套接字在运输层的可自定义性很低

运输服务

应用层协议

DNS

提供了主机名和 IP 地址之间相互转换的服务

DNS服务器层次结构

DNS是一个超大型的AP缓存系统,所以一个域名解析绑定全部生效要很久

返回的结果时一个四元组(name,value,type,ttl)

ttl是缓存的失效时间

可以使用 UDP 或者 TCP 进行传输,使用的端口号都为 53。大多数情况下 DNS 使用 UDP 进行传输,这就要求域名解析器和域名服务器都必须自己处理超时和重传从而保证可靠性

只有当返回的响应超过512字节或者主域名服务器向辅助域名服务器传送变化的数据时采用TCP协议

迭代查询

sequenceDiagram
  用户 ->> 本地DNS: 请求
  本地DNS ->> 根DNS: 请根DNS发起解析请求
  根DNS ->> 本地DNS: 返回顶级域名DNS地址
  本地DNS ->> 顶级域名DNS: 发起解析请求
  顶级域名DNS ->> 本地DNS: 返回权威DNS地址
  本地DNS ->> 权威DNS: 查询域名
  权威DNS ->> 本地DNS: IP
  本地DNS ->> 用户: IP

本地DNS收到查询请求后,会按照“是否有www.xxx.com.cn的权威服务器”→“是否有xxx.com.cn的权威服务器”→“是否有com.cn的权威服务器”→“是否有cn的权威服务器”的顺序,依次查询自己的地址记录,如果一直没有找到 就会找到根域名服务器为止

最后它将会得到“cn的权威服务器”的地址记录,然后通过“cn的权威服务器”,得到“com.cn的权威服务器”的地址记录,以此类推,最后找到能够解释www.xxx.com.cn的权威服务器地址

递归查询

sequenceDiagram
  用户 ->> 本地DNS: 域名
  本地DNS ->> 根DNS: 域名
  根DNS ->> 顶级域名DNS: 域名
  顶级域名DNS ->> 权威DNS: 域名
  权威DNS ->> 顶级域名DNS: IP
  顶级域名DNS ->> 根DNS: IP
  根DNS ->> 本地DNS: IP
  本地DNS ->> 用户: IP

域名解析记录

DNS报文

DNS报文格式

DNS预取优化

<!-- 加上这个标签 浏览器就会提前解析DNS 避免DNS解析带来的延迟问题 -->
<link rel="dns-prefetch" href="//domain.not-icyfenx.cn">  

HTTPDNS

一种通过HTTPS协议开发的DNS查询服务,应用程序可以直接跳过操作系统主动查询。使用 HTTPDNS 的,往往是手机应用,需要在手机端嵌入支持 HTTPDNS 的客户端 SDK

客户端,可以知道手机是哪个国家、哪个运营商、哪个省,甚至哪个市,HttpDNS 服务端可以根据这些信息,选择最佳的服务节点访问,如果有多个节点,还会考虑错误率、请求时间、服务器压力、网络状况等,进行综合选择,当有一个节点宕机或者性能下降的时候,可以尽快进行切换

sequenceDiagram
    participant ClientSDK
    participant LocalCache
    participant AppServer
    participant HttpDNSServer

    ClientSDK->>LocalCache: 获取本地IP列表缓存
    ClientSDK->>LocalCache: 查询地址是否已缓存
    LocalCache-->>ClientSDK: 返回缓存结果

    alt 缓存中存在结果
        ClientSDK->>AppServer: 发起请求
        AppServer-->>ClientSDK: 返回响应
    else 缓存中不存在结果
        ClientSDK->>HttpDNSServer: 请求IP列表
        HttpDNSServer-->>ClientSDK: 返回IP列表
        ClientSDK->>LocalCache: 缓存IP列表
        ClientSDK->>AppServer: 发起请求
        AppServer-->>ClientSDK: 返回响应
    end

攻击DNS

得益于DNS的分布式,DNS拥有很高的健壮性

FTP

FTP 使用 TCP 进行连接,它需要两个连接来传送一个文件:

主动模式(PORT)

主动模式下,客户端随机打开一个大于 1024 的端口 N,向服务器的命令端口 21 发起连接,同时开放 N+1 端口监听,并向服务器发出 “port N+1” 命令,由服务器从自己的数据端口 20,主动连接到客户端指定的数据端口 N+1

被动模式(PASV)

被动模式下,当开启一个 FTP 连接时,客户端打开两个任意的本地端口 N(大于 1024)和 N+1。第一个端口连接服务器的 21 端口,提交 PASV 命令。然后,服务器会开启一个任意的端口 P(大于 1024),返回“227 entering passive mode”消息,里面有 FTP 服务器开放的用来进行数据传输的端口。客户端收到消息取得端口号之后,会通过 N+1 号端口连接服务器的端口 P,然后在两个端口之间进行数据传输

通过代理连接FTP

FTPClient client = new FTPHTTPClient(config.getProxyHost(), config.getProxyPort());
// 当将 IPv4 与 NAT 一起使用时,它可能适用于一些罕见的配置。如果 FTP 服务器具有静态 PASV 地址(外部网络)并且客户端来自另一个内部网络。 在这种情况下,PASV 命令后的数据连接将失败,而 EPSV 将通过仅占用端口使客户端成功
client.setUseEPSVwithIPv4(true);
// connect and login...

DHCP

Dynamic Host Configuration Protocol

工作过程

屏幕截图 2022-06-09 202719

电子邮件协议

SMTP

SMTP 只能发送 ASCII 码,而互联网邮件扩充 MIME 可以发送二进制文件。MIME 并没有改动或者取代 SMTP,而是增加邮件主体的结构,定义了非 ASCII 码的编码规则

20203710108

SMTP服务器之间是点对点的,一般不会有中间转发者

POP3

从服务器上读取了邮件,就把该邮件删除

IMAP

客户端和服务器上的邮件保持同步

常用端口

应用 应用层协议 端口号 传输层协议 备注
域名解析 DNS 53 UDP/TCP 长度超过 512 字节时使用 TCP
动态主机配置协议 DHCP 67/68 UDP
简单网络管理协议 SNMP 161/162 UDP
文件传送协议 FTP 20/21 TCP 控制连接 21,数据连接 20
远程终端协议 TELNET 23 TCP
超文本传送协议 HTTP 80 TCP
简单邮件传送协议 SMTP 25 TCP
邮件读取协议 POP3 110 TCP
网际报文存取协议 IMAP 143 TCP

P2P

BT协议

.torrent 文件里的内容:

下载器通过下载种子文件,解析文件里的 Tracker 服务器地址,Tracker 服务器回应下载者的请求,将其他下载者(包括发布者)的 IP 提供给下载者,每下载到一个块,需要算出下载块的 Hash 验证码,并与.torrent 文件中的对比

DHT去中心化网络

任何一个 BitTorrent 启动之后,它都有两个角色。一个是 peer,监听一个 TCP 端口,用来上传和下载文件,这个角色表明,我这里有某个文件。另一个角色 DHT node,监听一个 UDP 的端口,通过这个角色,这个节点加入了一个 DHT 的网络

一个web页面请求过程

DHCP配置主机信息

主机刚开始没有IP地址信息,首先通过DHCP来获取IP地址 主机生成一个DHCP UDP请求报文 该请求报文被放入一个具有广播地址的IP数据报中 后该IP数据报被封装在MAC帧中,这个帧的目的地址是一个广播地址 当DHCP服务器接收到这个广播帧后不断向上分解得到主机信息,并将相关信息放入报文中,发送给主机 交换机通过自学习,因此现在交换机就可以直接知道应该向哪个接口发送该帧 主机收到该帧之后,配置自己的IP地址,子网掩码等信息

ARP解析MAC地址

主机需要跟网关路由器通信,但是DHCP 过程只知道网关路由器的 IP 地址 为了获取MAC地址,主机需要生成一个包含网关路由器地址的ARP查询报文,并将它广播出去 网关路由器接收到这个广播报文之后,向主机回送网关路由器自己的MAC地址

DNS解析域名

此时,主机可以直接通过网关路由器发送一个DNS请求报文 路由器收到这个DNS查询报文的帧后,抽取出IP数据报,根据转发表决定应该转发给哪台路由器 路由器通过内部网关协议和外部网关协议来实现路由选择 这个DNS请求到达服务器之后,DNS进行查询,发送DNS回答报文,回送给主机

HTTP请求页面

此时,主机就得到HTTP服务器的IP地址 会经过三次握手生成一个TCP套接字 TCP连接建立后,客户端生成一个HTTP请求报文,发送给服务器 服务器接收到之后,返回一个响应报文 客户端接收到响应之后,进行渲染,显示web页面