FeelingLife FeelingLife
首页
  • Go

    • Go基础知识
  • Python

    • Python进阶
  • 操作系统
  • 计算机网络
  • MySQL
  • 学习笔记
  • 常用到的算法
  • Docker
  • Kubernetes
  • Observability
  • 容器底层
其他技术
  • 友情链接
  • 收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

xuqil

一介帆夫
首页
  • Go

    • Go基础知识
  • Python

    • Python进阶
  • 操作系统
  • 计算机网络
  • MySQL
  • 学习笔记
  • 常用到的算法
  • Docker
  • Kubernetes
  • Observability
  • 容器底层
其他技术
  • 友情链接
  • 收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 应用层
    • 应用层协议原理
      • 套接字
      • 对进程进行编址
      • 传输层提供的服务
      • TCP Socket
      • UDP Socket
      • 传输层给应用层提供的服务
      • internet传输层提供的服务
      • TCP服务
      • UDP服务
      • 安全TCP
    • HTTP(超文本传输协议)
      • HTTP连接
      • HTTP方法类型
      • HTTP响应状态码
    • DNS(Domain Name Server)
      • DNS的总体思路和目标
      • DNS记录
      • DNS大致工作过程
      • 名字服务器及其查询方式
      • 名字服务器
      • 查询方式
    • Socket编程
      • UDP Socket
      • TCP Socket
  • 运输层
  • 抓包

  • 网络编程

  • 云网络

  • 虚拟网络

  • 常见面试题
  • 《计算机网络知识》
xuqil
2022-09-08
目录

应用层

# 应用层协议原理

互联网流行的应用层协议:

  • HTTP
  • FTP
  • SMTP/POP3/IMAP
  • DNS

网络应用的例子:

  • E-mail
  • Web
  • 文本消息
  • 远程登录
  • P2P共享文件
  • 即时通讯
  • 多用户网络游戏
  • 流媒体
  • Internet电话
  • 实时电视会议
  • 社交网络
  • 搜索
  • ......

网络应用的体系架构

  • 客户-服务器模式(C/S:client/server)
  • 对等模式(P2P:peer to peer)
  • 混合体:客户-服务器和对等体系结构

# 套接字

套接字用于解决分布式进程的通信(即不同主机间进程的通信)。同一主机内的进程,使用进程间通信机制通信(操作系统定义)。

# 对进程进行编址

一个进程:用IP+PORT标示端节点。本质上,一对主机进程之间的通信由2个端节点构成。

一些知名端口号的例子:

  • HTTP:TCP 80
  • Mail:TCP 25
  • FTP:TCP 21

# 传输层提供的服务

image-20220407195633959

层间接口必须要携带的信息:源IP、源TCP(UDP)端口号、目标IP和目标TCP(UDP)端口号

# TCP Socket

对于使用面向连接服务(TCP)的应用而言,套接字是4元组的一个具有本地意义的标示

  • 4元组:(源IP,源port,目标IP,目标port)
  • 唯一的指定了一个会话(2个进程之间的会话关系)
  • 应用使用这个标示,与远程的应用进程通信
  • 不必在每一个报文的发送都要指定这4元组
  • 就像使用操作系统打开一个文件,OS返回一个文件句柄一样,以后使用这个文件句柄,而不是使用这个文件的目录名、文件名
  • 简单,便于管理

# UDP Socket

对于使用无连接服务(UDP)的应用而言,套接字是2元组的一个具有本地意义的标示

  • 2元组:IP,port (源端指定)
  • UDP套接字指定了应用所在的一个端节点(end point)
  • 在发送数据报时,采用创建好的本地套接字(标示ID),就不必在发送每个报文中指明自己所采用的ip和port
  • 但是在发送报文时,必须要指定对方的ip和udp port(另外一个段节点)

# 传输层给应用层提供的服务

应用层需要传输层提供的服务?如何描述传输层的服务?

  • 数据丢失率
  • 吞吐
  • 延迟
  • 安全

# internet传输层提供的服务

# TCP服务

  • 可靠的服务
  • 流量控制:发送方不会淹没接收方
  • 拥塞控制:当网络拥塞时,能抑制发送方
  • 面向连接:要求客户端进程与服务端进程之间建立连接
  • 不能提供的服务:时间保证、最小吞吐量和安全

# UDP服务

  • 不可靠的数据传输
  • 不提供的服务:可靠,流量控制、拥塞控制、时间、宽带保证、建立连接

UDP存在的必要性

  • 能够区分不同的进程,而IP服务不能

    • 在IP提供的主机到主机端到端功能的基础上,区分了主机的应用进程
  • 无需建立连接,省去了建立连接时间,适合事务性的应用

  • 不做可靠性的工作,例如检错重发,适合那些对实时性要求比较高而对正确性要求不高的应用

    • 因为为了实现可靠性(准确性、保序等),必须付出时间代价(检错重发)
  • 没有拥塞控制和流量控制,应用能够按照设定的速度发送数据

    • 而在TCP上面的应用,应用发送数据的速度和主机向网络发送的实际速度是不一致的,因为有流量控制和拥塞控制

# 安全TCP

TCP & UDP

  • 都没有加密
  • 明文通过互联网传输,甚至密码

SSL

  • 在TCP上面实现,提供加密的TCP连接
  • 私密性
  • 数据完整性
  • 端到端的鉴别

SSL在应用层

  • 应用采用SSL库,SSL库使用TCP通信

SSL socket API

  • 应用通过API将明文交给socket,SSL将其加密在互联网上传输

# HTTP(超文本传输协议)

  • 使用TCP
  • HTTP是无状态的

# HTTP连接

非持久HTTP

  • 最多只有一个对象在TCP连接上发送
  • 下载多个对象需要多个TCP连接
  • HTTP/1.0使用非持久连接

持久HTTP

  • 多个对象可以在一个(客户端和服务器之间)TCP连接上传输
  • HTTP/1.1默认使用持久连接

# HTTP方法类型

HTTP/1.0

  • GET
  • POST
  • HEAD
    • 要求服务器在响应报文中不包含请求对象->故障跟踪

HTTP/1.1

  • GET
  • POST
  • HEAD
  • PUT
    • 将实体主体中的文件上载到URL字段规定的路径
  • DELETE
    • 删除URL字段规定的文件

# HTTP响应状态码

200 OK

  • 请求成功,请求对象包含在响应报文的后续部分

301 Moved Permanently

  • 请求的对象已经被永久转移了;新的URL在响应报文的Location:首部行中指定
  • 客户端软件自动用新的URL去获取对象

400 Bad Request

  • 一个通用的差错代码,表示该请求不能被服务器解读

404 Not Found

  • 请求的文档在该服务上没有找到

505 HTTP Version Not Supported

# DNS(Domain Name Server)

DNS负责域名与IP地址的转换。

# DNS的总体思路和目标

DNS的主要思路

  • 分层的、基于域的命名机制

  • 若干分布式的数据库完成名字到IP地址的转换

  • 运行在UDP之上端口号为53的应用服务

  • 核心的Internet功能,但以应用层协议实现

    • 在网络边缘处理复杂性

DNS主要目的

  • 实现主机名-IP地址的转换(name/IP translate)
  • 其它目的
    • 主机别名到规范名字的转换:Host aliasing
    • 邮件服务器别名到邮件服务器的正规名字的转换:Mail server aliasing
    • 负载均衡:Load Distribution

# DNS记录

DNS :保存资源记录(RR)的分布式数据库

RR 格式:(name, value, type, ttl)

type说明:

  • type=A(A记录)

    • name为主机名【即域名】
    • value为IP地址
  • type=CNAME

    • name为规范名字的别名

      www.ibm.com 的规范名字为 servereast.backup2.ibm.com

    • value为规范名字【即真正的域名】

  • type=NS

    • name为域名(如foo.com)【子域名字】
    • value为该域名的权威服务器的域名【子域名字服务器的名字】
  • type=MX

    • value为name对应的邮件服务器的名字

TTL:生存时间,决定了资源记录应当从缓存中删除的时间

# DNS大致工作过程

  • 应用调用解析器(resolver)
  • 解析器作为客户,向name server发出查询报文(封装在UDP段中)
  • name server返回响应报文(name/ip)

image-20220407194529667

# 名字服务器及其查询方式

# 名字服务器

  • 本地名字服务器(Local Name Server)
    • 无严格的分层结构
  • 名字服务器(Name Server)
    • 名字服务器的解析过程
      • 目标名字存在Local Name Server中
        • 情况1:查询的名字在该区域中
        • 情况2:缓存(cashing)

当与本地名字服务器不能解析名字时,联系根名字服务器顺着根-TLD 一直找到 权威名字服务器

# 查询方式

  • 递归查询
  • 迭代查询

# Socket编程

# UDP Socket

==UDP在客户端和服务器之间没有连接==

  • 没有握手
  • 发送端在每一个报文中明确地指定目标的IP地址和端口号
  • 服务器必须从收到的分组中提取出发送端的IP地址和端口号

==UDP传送的数据可能乱序,也可能丢失==

进程视角看UDP服务:UDP 为客户端和服务器提供不可靠的字节组的传送服务

image-20220407203013237

  • udpClient.py

    from socket import *
    
    server_name = 'localhost'
    server_port = 12000
    
    # 创建UDP Socket
    client_socket = socket(AF_INET, SOCK_DGRAM)
    
    # 输入需要传输的信息
    message = input(">")
    # 将服务器名称、端口附加到消息;发送到socket
    client_socket.sendto(message.encode(), (server_name, server_port))
    # 将套接字中的应答字符读到字符串
    modified_message, server_address = client_socket.recvfrom(2048)
    # 打印结果
    print(modified_message.decode())
    client_socket.close
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
  • udpServer.py

    from socket import *
    
    server_port = 12000
    # 创建UDP Socket
    server_socket = socket(AF_INET, SOCK_DGRAM)
    # 绑定本地端口号12000
    server_socket.bind(("", server_port))
    print("The server is ready to receive")
    
    while True:
        # 从socket中接收消息和客户端地址(IP和端口号)
        message, client_address = server_socket.recvfrom(2048)
        modified_message = message.decode().upper()
        server_socket.sendto(modified_message.encode(), client_address)
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

# TCP Socket

==服务器首先运行,等待连接建立==

1、服务器进程必须先处于运行状态

  • 创建欢迎socket
  • 和本地端口捆绑
  • 在欢迎socket上阻塞式等待接收用户的连接

==客户端主动和服务器建立连接:==

2、创建客户端本地套接字(隐式捆绑到本地port)

  • 指定服务器进程的IP地址和端口号,与服务器进程连接

3 、当与客户端连接请求到来时

  • 服务器接受来自用户端的请求,解除阻塞式等待,返回一个新的socket(与欢迎socket不一样),与客户端通信
  • 允许服务器与多个客户端通信
  • 使用源IP和源端口来区分不同的客户端

4、连接API调用有效时,客户端P与服务器建立了TCP连接

从应用程序的角度:TCP在客户端和服务器进程之间提供了可靠的、字节流(管道)服务

image-20220407205156673

  • tcpClient.py

    from socket import *
    
    server_name = "localhost"
    server_port = 12000
    
    # 为远程服务器创建TCP Socket
    client_socket = socket(AF_INET, SOCK_STREAM)
    client_socket.connect((server_name, server_port))
    
    sentence = input(">")
    # No need to attach server name, port
    client_socket.send(sentence.encode())
    modified_sentence = client_socket.recv(1048)
    print('From Server:', modified_sentence.decode())
    client_socket.close()
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
  • tcpServer.py

    from socket import *
    
    server_port = 12000
    
    # 创建TCP Welcome Socket
    server_socket = socket(AF_INET, SOCK_STREAM)
    server_socket.bind(('', server_port))
    # server begins listening for incoming TCP requests
    server_socket.listen(1)
    print('The server is ready to receive')
    
    while True:
        # server waits on accept() for incoming requests, new socket created on return
        connection_socket, addr = server_socket.accept()
    
        # read bytes from socket (but not address as in UDP)
        sentence = connection_socket.recv(1024).decode()
    
        capitalized_sentence = sentence.upper()
    
        # close connection to this client (but not welcoming socket)
        connection_socket.send(capitalized_sentence.encode())
    
        connection_socket.close()
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
#应用层
上次更新: 2024/05/29, 06:25:22
运输层

运输层→

最近更新
01
VXLAN互通实验
05-13
02
VXLAN
05-13
03
VLAN
05-13
更多文章>
Theme by Vdoing | Copyright © 2018-2025 FeelingLife | 粤ICP备2022093535号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式