OSI 七层模型 1 应用层 【提供用户服务,具体功能由特定的程序而定】 2 表示层 【数据的压缩优化,加密】 3 会话层 【建立应用级的连接,选择传输服务】 4 传输层 【提供不同的传输服务,流量控制】 5 网络层 【路由选择,网络互连】 6 链路层 【进行数据转换,具体消息的发送,链路连接】 7 物理层 【物理硬件,接口设定,网卡路由交换机等】
cookie 高内聚 : 模块功能尽可能单一,不要掺杂 低耦合 : 模块之间尽量减少关联和影响 OSI 模型优点 1 将工作流程标准化 2 降低了模块间的耦合度,使每一部分可以单独开发,单独工作 四层模型 1 应用层 【:集合了原有的应用层,表示层,会话层】 2 传输层 3 网络层 4 物理链路层
五层模型(TCP/IP模型) 1 应用层 2 传输层 3 网络层 4 链路层 5 物理层 数据传输流程 1 发送端由应用层到物理层逐层添加信息头(首部),最终在物理层发送。 2 中间经过节点(交换机,路由器等。。)转发,发送到接收端 3 在接收端根据发送端的每个信息头进行解析,最终消息到应用层展示给用户 网络协议 : 在网络通信中双方都遵循的规定,包括建立什么样的网络结构,消息结构,标识代表什么等。 应用层协议 : TFTP HTTP DNS SMTP 传输层协议 : TCP UDP 网络层 : IP 物理层 : IEEE 网络相关概念 网络主机 : 在网络中标识一台计算机 HOST 本地使用 :'localhost' '127.0.0.1' 网络使用 : '0.0.0.0' '本机IP' IP地址 网络上确定一台主机网络位置的地址 IPV4 : 点分十进制 占32位 IPV6 : 128位 将IP十进制转化为二进制 > socket.inet_aton('192.168.0.1') > 'b\xxxx' 将IP 二进制转化为十进制 > socket.inet_ntoa('b\xxxx') 域名 :网络服务器地址的名称 1,方便记忆 2,名称表达一定的含义 网络端口号 端口是网络地址的一部分,用于区分一个网络主机上的网络应用 * 在一个操作系统中不同的网络应用监听不同的端口号 取值范围 : 1~~65535 1~~255 : 一些众所周知的通用端口 256~~1023 : 系统应用端口 1024 ~~ 65535 :自用端口 建议使用 >10000的端口 socket.getservbyname('http') 【返回对应应用的端口信息】 -->80 网络字节序 传输层服务 面向连接的传输服务 基于tcp协议的数据传输 传输特征 : 提供可靠的数据传输,可靠性指数据传输过程中无丢失,无失序,无差错,无重复。 实现手段: 数据传输断开前都需要进行传输和断开的确认 三次握手: TCP在数据传输前建立连接的过程 1 客户端向服务器发送连接请求 2 服务器收到请求后,回复确认消息,表示允许连接 3 客户端收到服务器回复,进行最终标志发送确认连接
四次挥手: TCP传输在连接断开前进行断开确认的过程 1 主动发发送报文告知被动方要断开连接 2 被动方收到请求后立即返回报文告知已经准备断开 3 被动方准备就绪后再次发送报文告知可以断开 4 主动方发送消息,确认最终断开
应用情况 : 适用于传输较大的文件,网络情况良好,需要保证传输可靠性的情况 比如 : 网页的获取,文件下载,邮件传输,登录注册
面向无连接的传输服务 基于UDP协议的传输 传输特点 : 不保证传输的可靠性,传输过程没有连接和断开的流程,数据收发自由 应用情况 : 网络情况较差,对传输可靠性要求不高峰,需要提升传输效率。不变连接,需要灵活收发消息。 比如:网络视频,群聊,广播发送
服务端 1 创建SOCK对象,流式 (socket.AF_INET,socket.SOCK_STREAM) 2 绑定服务地址和端口 3 监听端口 4 等待连接 5 消息收发 6 关闭
import socket,selectors,timeepoll=selectors.DefaultSelector()host='127.0.0.1'port=8889s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.bind((host,port))s.listen(10)while True: conn, add = s.accept() try: while True: a=conn.recv(1024) print(a) if a.decode('utf8')=='##': break conn.send(a) conn.close() except: conn.close()s.close()
客户端 1 创建SOCK对象 2 建立连接 connet 3 消息收发 4 关闭
import socket,times=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect(('127.0.0.1', 8889))while True: s.send(bytes('你好',encoding='utf8')) time.sleep(2) a=s.recv(1024) print(a.decode('utf8'))
UDP
套接字传输注意事项 1 监听套接字存在客户端即可发起连接,但是最终连接的处理需要accept进行处理 2 如果连接的另外一段,则recv会立即返回空子串不再阻塞 3 当连接的另一端退出时,再试图send 发送就会产生 BrokenPipeError 网络收发缓冲区 缓冲区作用: 1 协调收发(处理)速度 2 减少交互次数 send和recv 实际上是和缓冲区进行交互,发送缓冲区满时就无法发送,接收缓冲区满时recv才阻塞 TCP粘包 产生原因: tcp 套接字以字节流方式传输,没有消息边界 发送和接收并不能保证每次发送都及时的被接收 影响: 如果每次发送内容表达一个独立的含义此时可能需要处理粘包防止产生歧义 处理方法 1 每次发送的消息添加结尾标志(人为增加消息边界) 2 发送数据结构体 3 协调收发速度,每次收发后都预留接收时间 UDP 1 创建数据报套接字 (sock.AF_INFT,sock.SOCK_DGRAM)
2 绑定地址 bind 3 消息的收发 4 conn,addr = s.recvfrom(buffersize) 参数 :接收UDP消息 返回值 :data 接收到的数据 addr 消息发送端的地址 sockfd.sendto(datamaddr) 功能 :发送UDP消息 参数 :data 发送的消息 bytes格式 addr 目标地址 返回值 :发送的字节数 5 关闭套接字 socket.close()
网络收发缓冲区 缓冲区作用: 1 协调收发(处理)速度 2 减少交互次数 send和recv 实际上是和缓冲区进行交互,发送缓冲区满时就无法发送,接收缓冲区满时recv才阻塞 TCP粘包 产生原因: tcp 套接字以字节流方式传输,没有消息边界 发送和接收并不能保证每次发送都及时的被接收 影响: 如果每次发送内容表达一个独立的含义此时可能需要处理粘包防止产生歧义 处理方法 1 每次发送的消息添加结尾标志(人为增加消息边界) 2 发送数据结构体 3 协调收发速度,每次收发后都预留接收时间 UDP 1 创建数据报套接字 2 绑定地址 bind 3 消息的收发 4 conn,addr = s.recvfrom(buffersize) 参数 :接收UDP消息 返回值 :data 接收到的数据 addr 消息发送端的地址 sockfd.sendto(datamaddr) 功能 :发送UDP消息 参数 :data 发送的消息 bytes格式 addr 目标地址 返回值 :发送的字节数 5 关闭套接字 socket.close()
View Code_服务端
View Code——客户端
添加程序第一行 #!/usr/bin/env python3 TCP套接字编程和UDP套接字编程区别 1 流式套接字使用字节流的方式传输,数据报套接字以数据报形式传输数据 2 TCP 会有粘包现象,UDP有消息边界不会形成粘包 3 TCP 可以保障数据传输完整性,UDP则不保证 4 TCP 需要进行listen accept 操作UDP不需要 5 TCP收发消息使用新的套接字,recv send ,udp 使用recvfrom sendto 补充函数 sendall() 功能 : 发送 TCP 消息 参数 : 要发送的内容,bytes格式 返回值 : 成功返回None,失败产生异常