(day27)subprocess模块+粘包问题+struct模块+ UDP协议+socketserver
目录
昨日回顾
软件开发架构
C/S架构
Client:客户端
Server:服务端
优点
占用网络资源少,软件的使用稳定
缺点
用户在使用多个软件要下载客户端,软件每次更新用户也需要更新
用户体验差
B/S架构
Broser:浏览器
Server:服务端
优点
用户不需要下载多个客户端,以浏览器充当所有软件的客户端
缺点
网络资源占用较大,网络不稳定时,软件的使用也不稳定
网络编程
- 实现远程通信
- 物理连接介质:网卡等
- 互联网协议
互联网协议
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层
物理层
- 基于电信号发送一堆二进制数据
数据链路层
把二进制数据交给"以太网协议"处理:
规定好电信号的分组方式
必须要有一个网卡
mac的地址
由12位唯一的编码
前6位:厂商号
后6位:流水号
以太网协议
- 广播,单播
- 弊端:广播风暴,无法跨局域网通信
交换机
让多台电脑连接在一起
互联网
让所有电脑都互联到一起
网络层
连接到互联的电脑都需要有一个IP地址
- IP地址
- 用于唯一标识计算机(局域网)具体位置
- 点分十进制
- 最小值:0.0.0.0
- 最最大值:255.255.255.255
传输层
TCP/UDP协议
TCP:流式协议
基于TCP协议进行通信,必须要创建双向通道
- 一个是客户端往服务端的管道
- 一个是服务端往客户端的管道
三次握手,四次挥手
反馈机制
客户端发送信息,服务端,必须返回确认机制,否则客户端会一直发送请求
应用层
- http(重点),ftp(了解)
socket套接字
# 服务端.py
import socket
server = socket.socket()
server.bind(('127.0.0.1',8888))
server.listen(5) # 半连接池
while True:
conn,addr = server.accept()
while True:
try:
data = conn.recv(1024).decode('utf-8') # recv数据从内存中获取
if data == 'q':
break
print(data)
conn.send(data.encode('utf-8'))
except Exception as e:
print(e)
break
conn.close()
# 客户端.py
import socket
client = socket.socket()
client.connect(('127.0.0.1'.8888))
while True:
msg = input('>>')
client.send(msg.encode('utf-8'))
if msg == 'q':
break
data = client.recv(1024).decode('utf-8')
print(data)
client.close()
今日内容
一、subprocess模块
可以通过代码执行操作系统的终端命令
并返回终端执行命令的结果
import subprocess
cmd = input('cmd>>>:')
obj = subprocess.popen(
cmd, # cmd命令
Shell = True,
stdout = subprocess.PIPE, # 返回正确结果
stderr = subprocess.PIPE # 返回错误结果
)
data1 = obj.stdout.read()
data2 = obj.stderr.read()
result = data1 + data2
print(result.decode('gbk'))
二、粘包问题
- 服务端第一次发送的数据,客户端无法精确一次性接受完毕,下一次发送的数据就与上一次数据粘在一起
- 无法预测对象需要接受的数据大小长度
- 多次连续发送数据量小,并且间隔时间短的数据一次性打包发送过去
TCP协议特性
TCP是一个流式协议,会将多次连续发送数据量小,并且间隔时间短的数据一次性打包发送过去
三、struct模块
解决粘包问题, 是一个可以将很长的数据的长度,压缩成固定的一个标记(数据包头)
- 必须先定义报头,发送报头,在发送真实数据
import struct # 打包压缩 # i:模式,会将数据长度压缩成4个bytes str = '1123fsgsdasfdasfaa' # 模拟客户端 # 包头 headers = struct.pack('i',len(str)) print(len(headers)) # 4 # 模拟服务端 # headers = conn.recv(4) datalen = struct.unpack('i',headers) # 元组(len(str),) print(data_len[0]) # len(str)既想发送文件,又想发送文件的描述信息
客户端发送字典给服务端
# 服务端.py import socket import json import struct server = socket.socket() server.bind( ('127.0.0.1', 9527) ) server.listen(5) while True: conn, addr = server.accept() while True: try: # 先接收报头 headers = conn.recv(4) # 解包获取真实数据长度 data_len = struct.unpack('i', headers)[0] # 获取字典数据真实长度 bytes_data = conn.recv(data_len) back_dic = json.loads(bytes_data.decode('utf-8')) print(back_dic) except Exception as e: print(e) break conn.close()# 客户端.py import socket import struct import json import time client = socket.socket() client.connect( ('127.0.0.1', 9527) ) while True: send_dic = { 'file_name': 'jason真实写真集.avi', 'file_size': 10000000 # 10G } # json序列化,并转码成bytes类型数据 json_data = json.dumps(send_dic) bytes_data = json_data.encode('utf-8') # 先做报头 headers = struct.pack('i', len(bytes_data)) client.send(headers) client.send(bytes_data) time.sleep(10)
四、UDP
UDP是一种传输协议
- 不需要建立双向通道
- 不会粘包
- 客户端给服务端发送数据不需要等待服务端返回接受成功
- 数据容易丢失,不安全
# 服务端
import socket
# SOCK_DGRAM:代表UDP
server = socket.scoket(type = socket.SOCK_DGRAM)
server.bind(('127.0.0.1',9527))
msg, addr = server.recvfrom(1024)
# 客户端
import socket
client = socket.socket(type = socket.SOCK_DGRAM)
server_ip_port = ('127.0.0.1',9527)
client.sendto(b'hello',server_ip_port)
五、QQ聊天室
基于UDP实现QQ聊天室
# 服务端
import socket
server = socket.socket(type = socket.SOCK_DGRAM)
server.bind(('127.0.0.1',9527))
while True:
msg,addr = server.recvfrom(1024)
print(addr)
print(msg.decode('utf-8'))
send_msg = input('服务端:')
server.sendto(send_msg.encode('utf-8'),addr)
# 客户端
import socket
client = socket.socket(type = socket.SOCK_DGRAM)
addr= ('127.0.0.1',9527)
while True:
send_msg = input('客户端1:')
client.sendto(send_msg.encode('utf-8'),addr)
back_msg ,addr= client.recvfrom(1024)
print(back_msg.decode('utf-8'))
六、SocketServer
python内置模块,可以简化socket套接字TCP/UDP服务端的代码
import socketserver
# 定义类
class MyTcpServer(socketserver.BaseRequestHandler)
# 重新父类的handler
def handler(self):
# 1. 接收消息
data = self.request.recv() # conn.recv(1024)
# 2. 给客户端发送消息
send_msg = input('服务端:').encode('utf-8')
self.request.send(send_msg)
if __name__= '__main__':
server = socketserver.TCPserver(('127.0.0.1',8888),MyTcpServer)
server.serve_forever()
(day27)subprocess模块+粘包问题+struct模块+ UDP协议+socketserver的更多相关文章
- python笔记8 socket(TCP) subprocess模块 粘包现象 struct模块 基于UDP的套接字协议
socket 基于tcp协议socket 服务端 import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 买 ...
- 8.7 day28 网络编程 socket套接字 半连接池 通信循环 粘包问题 struct模块
前置知识:不同计算机程序之间的数据传输 应用程序中的数据都是从程序所在计算机内存中读取的. 内存中的数据是从硬盘读取或者网络传输过来的 不同计算机程序数据传输需要经过七层协议物理连接介质才能到达目标程 ...
- python网络编程-socket套接字通信循环-粘包问题-struct模块-02
前置知识 不同计算机程序之间数据的传输 应用程序中的数据都是从程序所在计算机内存中读取的. 内存中的数据是从硬盘读取或者网络传输过来的 不同计算机程序数据传输需要经过七层协议物理连接介质才能到达目标程 ...
- 网络编程基础:粘包现象、基于UDP协议的套接字
粘包现象: 如上篇博客中最后的示例,客户端有个 phone.recv(2014) , 当服务端发送给客户端的数据大于1024个字节时, 多于1024的数据就会残留在管道中,下次客户端再给服务端发命令时 ...
- day31——recv工作原理、高大上版解决粘包方式、基于UDP协议的socket通信
day31 recv工作原理 源码解释: Receive up to buffersize bytes from the socket. 接收来自socket缓冲区的字节数据, For the opt ...
- UDP协议&socketserver模块
UDP协议&socketserver模块 一.UDP协议 1.1 UDP实现简单通信 服务器 ------------------------------------------------- ...
- socker通信-struct模块-粘包问题
Socket概念 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对 ...
- python tcp黏包和struct模块解决方法,大文件传输方法及MD5校验
一.TCP协议 粘包现象 和解决方案 黏包现象让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)执行远程命令的模块 需要用到模块subprocess sub ...
- scoket模块 粘包问题 tcp协议特点 重启服务器会遇到地址被占用问题
scoket()模块函数用法 import socket socket.socket(socket_family,socket_type,protocal=0) 获取tcp/ip套接字 tcpsock ...
随机推荐
- jenkins自动化部署项目9 --定时构建
举几个例子:每隔5分钟构建一次H/5 * * * * 每两小时构建一次H H/2 * * * 每天中午12点定时构建一次H 12 * * * 每天下午18点定时构建一次H 18 * * * 在每个小时 ...
- Maven 梳理 - 核心概念
Maven坐标 依赖配置 依赖范围 依赖范围scope用来控制依赖和编译,测试,运行的classpath的关系. 主要的是三种依赖关系如下: 1.compile: 默认编译依赖范围.对于编译,测试,运 ...
- Hadoop点滴-初识MapReduce(1)
分析气候数据,计算出每年全球最高气温(P25页) Map阶段:输入碎片数据,输出一系列“单键单值”键值对 内部处理,将一系列“单键单值”键值对转化成一系列“单键多值”键值对 Reduce阶段,输入“单 ...
- Java8新特性——stream流
一.基本API初探 package java8.stream; import java.util.Arrays; import java.util.IntSummaryStatistics; impo ...
- 在window里面安装ubuntu子系统并安装图形化界面
一.开启windows子系统 1. 在win10设置里面开启开发人员选项 (设置-->更新安全--> 开发者选项 )选择开启 2.在控制面板里面开启windows子系统 (启用或关闭wi ...
- Centeos7部署Flask+Gunicorn+nginx
一.环境安装 pip3 install flask pip3 install gunicorn pip3 install nginx 二.模块介绍 1.Flask是一个使用 Python 编写的轻量级 ...
- golang学习之路
目录 go语言介绍 开发环境准备 go语言基础 Go语言常用标准库 数据库相关 前端相关 web开发 go语言介绍 为什么要学习go语言 开发环境准备 从零开始搭建Go语言开发环境 VS Code配置 ...
- Video/audio标签的一些基础使用心得
常用方法 .play():用于音频视频的播放 .pause():用于音频视频的暂停 常用属性 <audio src="Batmobile Battle Mode Reveal Musi ...
- MySQL 和 Navicat Premium 下载及安装全过程
前言: 我对 “MySQL社区版” 的理解是:它只是一个后台服务,它的管理需要用到其他的数据库管理软件,这里我用的是 Navicat Premium,这个软件可以同时为多个数据库提供管理,比如MySQ ...
- C-01 手写数字识别
目录 手写数字识别应用程序 一.导入模块 二.图像转向量 三.训练并测试模型 四.模型转应用程序 4.1 展示图片 4.2 处理图片 4.3 预测图片 更新.更全的<机器学习>的更新网站, ...