(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 ...
随机推荐
- Android Studio [跑马灯]
MainActivity package com.xdw.secondapp; import android.graphics.Paint; import android.support.v7.app ...
- win10 更新之后,软件路径被改为*
win 10 更新到最新版之后,软件安装盘符被改为* ,导致软件打开失败,截图如下: 1. 首先先下载一个RegistryWorkshop 地址:https://sm.myapp.com/origin ...
- Kotlin学习系列(一)
基本类型 在Kotlin中任何事物都是对象你可以在任何变量上调用相应的方法或属性.Kotlin的一些内置类型如下: Number: 包含整形与浮点型 Character: 字符(Chat) Boole ...
- mysql数据库安全性配置——日志记录
一:开启数据库日志记录 (1)在查看数据库是否开启日志记录,默认是OFF,即关闭状态.(可在数据库中执行该查询语句,也可在服务器端执行) show variables like 'log_bin'; ...
- 聚类算法之K-means
想想常见的分类算法有决策树.Logistic回归.SVM.贝叶斯等.分类作为一种监督学习方法,要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别与之对应.但是很多时候上述条件得不到满 ...
- 使用Hugo,只需5分钟,轻松搭建一个自己的博客
前面跟大家介绍过hexo这款静态博客系统,功能强大,基本能满足博客的各种需求.今天,我再跟大家介绍一款优秀的静态博客系统,那就是Hugo. Hugo是由Go语言实现的静态网站生成器.简单.易用.高效. ...
- How to setup Electrum testnet mode and get BTC test coins
For some reason we need to use BTC test coins, but how to set up the Bitcoin testnet wallet and get ...
- php-fpm启动,重启,退出
首先确保php-fpm正常安装,运行命令php-fpm -t输出查看: ##确定php-fpm配置正常 [root@iz2vcf47jzvf8dxrapolf7z php7.-Oct-::] NOTI ...
- Python之——爱心代码参与情人节
一行代码实现输出爱心图,参考https://zhuanlan.zhihu.com/p/23321351 原理: 1.借助数学函数——((x * 0.05) ** 2 + (y * 0.1) ** 2 ...
- JavaScript 面向对象编程 · 理解对象
前言: 在我们深入 面向对象编程之前 ,让我们先理解一下Javascript的 对象(Object),我们可以把ECMAScript对象想象成散列表,其值无非就是一组名值对,其中值可以是数据 ...