socketserver模块用法,多道技术、 基于UDP的简易版QQ
1、OSI七层
2、以太网协议
3、ip协议(arp协议)
4、TCP
5、UDP
OSI七层
应表会 # 应用层 (HTTP协议, FTP协议)
传输层 # 端口协议 在此层发挥作用
网络层 # IP协议 在此层发挥作用
数据链路层 # 以太网协议(arp协议) 在此层发挥作用
物理连接层
以太网协议
1、规定了电信号的分组方式
2、每台计算机都必须有一块网卡,网卡上可有12位16进制的编号
前6位代表生产厂家, 后6位代表生产流水线
我们把这个编号称之为mac地址
以太网协议特点:通信基本靠吼
缺点:广播风暴
ip协议(arp协议) | 端口
ip协议规定任何结束互联网的计算机都必须拥有一个独一无二的地址
版本:ivp4 | ivp6
特点:点分十进制
作用:能够标识全世界独一无二的一台计算机
port(端口):
标识计算机中唯一一个基于网络通信的应用程序
范围:0 - 65535
0 - 1024 被系统占用
MySQL:3306
Redis:6379
Flask:5000
Django:8000
ip+port:标识唯一一台计算机上的唯一联网通信的应用程序
arp协议:根据ip地址解析mac地址
TCP
三次握手
四次挥手
粘包问题:
1、发送方因流式协议一次性发送短间隔数据量小的数据
2、接收方不知道要接受的长度
今日内容
1、UDP
2、socketserver模块
3、并发编程概念
UDP
数据报协议
没有双向通道
1、UDP协议不存在粘包问题
2、客户端可以发空
3、UDP可以实现并发
4、服务端不存在也不影响客户端往服务端发送数据
示例:
# server端:
import socket
server = socket.socket(type=socket.SOCK_DGRAM) # 要表明 type=UDP的标识符
server.bind(('127.0.0.1', 8080))
data, addr = server.recvfrom(1024)
# 接收结果为一个元组,第一个值为真实数据,第二个为客户端地址
server.sendto(data.upper(), addr) # 发送命令后要加客户端addr
# client端
import socket
client = socket.socket(type=socket.SOCK_DGRAM)
server_addr = ('192.0.0.1', 8080)
client.sendto(b'hello', server_addr)
data, addr = client.recvfrom(1024)
print(data.decode('utf-8'))
基于UDP实现简易版本的QQ
# 服务端
import socket
server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(('127.0.0.1', 8080))
while True:
msg, addr = server.recvfrom(1024)
print(addr)
print(msg.decode('utf-8'))
info = input('>>>:').encode('utf-8')
server.sendto(info, addr)
server.close()
# 多个客户端
import socket
client = socket.socket(type=socket.SOCK_DGRAM)
server_addr = ('127.0.0.1', 8080)
while True:
info = input('>>>:')
info = ('来自客户端1的消息:%s'%info).encode('utf-8') # 改中文备注即可
client.sendto(info, server_addr)
msg, addr = client.recvfrom(1024)
print(msg.decode('utf-8'), addr)
client.close()
小知识点补充:
windows电脑和max电脑的时间同步功能,其实就是基于UDP朝windows,mac服务器发送请求获取标准时间
TCP/UDP
TCP:打电话
UDP:发短信
socketserver模块
1、能够实现并发效果
并发:看起来像同时运行就叫并发
TCP与UDP中,socketserver用法相同
示例:
server端:
import socketserver
class MyServer(socket.BaseRequestHandler):
def handle(self):
try:
循环通信代码块
# TCP则是recv, send
# UDP则是recvfrom, sendto
except ConnectionReseError:
break
if __name__ == '__main__':
server = socket.ThreadingTCPServer(('127.0.0.1', 8080), MyServer)
# 上面一句代绑定地址与通信循环的代码, 在UDP中的写法是:
# server = socket.ThreadingUDPServer(('127.0.0.1', 8080), MyServer)
server.server_forever()
client端:
客户端写法不变,该是TCP就按TCP的写法来,该是UDP就按UDP的写法来
并发编程发展史
因为CPU利用率低,所以研发出了多道技术
多道技术:
- 空间上的复用(多个程序共一套硬件设备,它是多道技术实现时间上的复用的基础,
不然还要去硬盘读数据)
- 时间上的复用(单个cpu的电脑上,起多个应用程序。cpu快速切换,给人的感觉是同时运行)
cpu两种情况下才会切换:(先保存当前程序的运行状态)
- 一个任务占用cpu时间过长或被操作系统强行剥夺走cpu的执行权限(比起串行效率反而降低)
- 一个任务执行过程中遇到io操作,也会被操作系统强行剥夺走cpu的执行权限(比起串行效率提高)
并发:看上去像同时进行的
并行:同时进行
补充:单核的计算机不可能实现并行