python 并发编程(socketserver)
下面的例子是简单的ssh 登录,其实也就是客户端把指令发送给服务器。服务器把结果返还给客户端,客户端再在终端展现 服务端代码:
#Author:BigBao
#Date:2018/7/18
# 我们之前没有实现并发的原因是,我们之前是链接循环加通信循环,我们只有建立连接后才能通信,通信的过程中腾不出手来建立连接
# 所以现在我们得把链接循环和通信循环给分开,一个class一直在建立连接,一个class一直在通信
# 我们之前的是我们必须创建过链接之后立马去通信,通过过程中部可以去建立连接
'''
socketserver
封装了多进程,多线程
同时还封装了多路复用,把我们的程序性能发挥到机制
'''
import socketserver
import subprocess
import json
import struct
# 通信循环
class MyTcpHandler(socketserver.BaseRequestHandler): # BaseRequestHandler 专门用来负责处理通信相关信息的
def handle(self): # 这里必须定义一个handle方法,而且方法名必须是handle, sockerserver 会自动去调用handle这个方法
print(self.request) # 这里的self.request 相当于我们之前看到的conn那个对象( conn,client_addr=server.accept() )
while True:
try:
recv_cliend_cmd = self.request.recv(1024) #接收客户端的指令
if not recv_cliend_cmd:break
# 下面就要对客户端发送的指令进行处理了
obj=subprocess.Popen(recv_cliend_cmd.decode('utf-8'),shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
# 下面开始创建报头(随意写的),这里我们真正用到的就是字典里的total_size
header_dic={
'total_size':len(stdout)+len(stderr),
'filename':'xxx.mp4',
'md5sum':'8f6fbf8347faa4924a76856701edb0f3'
}
header_json = json.dumps(header_dic)
header_bytes = header_json.encode('utf-8')
self.request.send(struct.pack('i',len(header_bytes))) # 这个发送过去为固定的字节数 4 个,所以客户端第一次接收四个字节即可 self.request.send(header_bytes) self.request.send(stdout)
self.request.send(stderr) except ConnectionResetError:break
self.request.close() # 连接循环
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyTcpHandler) #基于Tcp的多线程服务端
server.serve_forever()
# 客户端发来请求,就建立一个连接,server 立马造一个线程,然后再把MyTcpHandler 类实例化得到一个对象,触发对象下面的handle方法,把连接丢给 handle 方法(handle方法下的self.request 就是建立的连接)
# 也就是说客户端来一个连接,建立后就会触发通信循环的的handle 方法,我们可以看一下self.request 打印出来的东西就是本地IP:端口 客户端IP:端口
客户端代码 #Author:BigBao
#Date:2018/7/18
import socket
import struct
import json
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',8080))
while True:
cmd = input('please input your cmd: ').strip()
if not cmd:continue
client.send(cmd.encode('utf-8'))
obj = client.recv(4)
header_size = struct.unpack('i',obj)[0]
header_bytes = client.recv(header_size)
header_json = header_bytes.decode('utf-8')
header_dic = json.loads(header_json)
total_size = header_dic['total_size']
recv_size = 0
res = b''
while recv_size < total_size:
recv_data = client.recv(1024)
res+=recv_data
recv_size+= len(recv_data)
print(res.decode('gbk'))
client.close()
我们上面处理的黏包问题是发生在服务端发数据给客户端,客户端的数据接收不完全的解决方案。要是涉及到两边都有黏包问题的话,解决方案也是上面一样解决
python 并发编程(socketserver)的更多相关文章
- Python并发编程-SocketServer多线程版
#server.py import socket from threading import Thread def chat(conn): conn.send(b'hello') msg = conn ...
- Python并发编程理论篇
Python并发编程理论篇 前言 其实关于Python的并发编程是比较难写的一章,因为涉及到的知识很复杂并且理论偏多,所以在这里我尽量的用一些非常简明的语言来尽可能的将它描述清楚,在学习之前首先要记住 ...
- Python并发编程__多进程
Python并发编程_多进程 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大 ...
- Python并发编程的几篇文章
Python几种并发实现方案的性能比较 http://www.elias.cn/Python/PyConcurrency?from=Develop.PyConcurrency python并发编程 h ...
- Python并发编程之深入理解yield from语法(八)
大家好,并发编程 进入第八篇. 直到上一篇,我们终于迎来了Python并发编程中,最高级.最重要.当然也是最难的知识点--协程. 当你看到这一篇的时候,请确保你对生成器的知识,有一定的了解.当然不了解 ...
- 自学Python之路-Python并发编程+数据库+前端
自学Python之路-Python并发编程+数据库+前端 自学Python之路[第一回]:1.11.2 1.3
- Python并发编程二(多线程、协程、IO模型)
1.python并发编程之多线程(理论) 1.1线程概念 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程(流水线的工作需要电源,电源就相当于 ...
- Python并发编程一(多进程)
1.背景知识(进程.多道技术) 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一 ...
- 《转载》Python并发编程之线程池/进程池--concurrent.futures模块
本文转载自Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mult ...
- Python并发编程系列之多线程
1 引言 上一篇博文详细总结了Python进程的用法,这一篇博文来所以说Python中线程的用法.实际上,程序的运行都是以线程为基本单位的,每一个进程中都至少有一个线程(主线程),线程又可以创建子线程 ...
随机推荐
- OpenERP 7中 openerp-server.conf 的解释
服务器启动配置 – 通用项 程序代码: [选择] # Admin password for creating, restoring and backing up databases admin_pas ...
- SSH黄金参数
ssh -o ConnectTimeout=3 -o ConnectionAttempts=5 -o PasswordAuthentication=no -o StrictHostKeyCheckin ...
- java常见数据结构整理
java中容器类数据结构主要在java.util包中. java.util包中三个重要的接口及特点:List(列表).Set(保证集合中元素唯一).Map(维护多个key-value键值对,保证key ...
- SElinux测试及排错
一.修改SElinux的状态 #sestatus --查看状态 #setenforce --临时修改 #setenforce #getenforce #vim /etc/selinux/config ...
- Unbound服务的安装与运行管理
一.Unbound服务的安装与运行管理 1.获取Unbound软件包 RHEL7.x自带了Bind和Unbound两种DNS服务包,Unbound是红帽公司推荐使用的DNS服务器.目前,虽然Bind在 ...
- 长按listview弹出选项列表对话框
Android中通过xml资源文件定义数组.来自微风的网络日志. 文章链接:http://leybreeze.com/blog/?p=1524 Android ListView两种长按弹出菜单方式 h ...
- iOS Main Thread Checker: UI API called on a background thread的解释
Xcode打印栏出现如下警告: Main Thread Checker: UI API called on a background thread 这个是什么错误呢? 其实这并不一定是错误,也可以理解 ...
- django日志使用TimeRotateFileHandler
如果使用django的settings.py设置日志会产生一些问题. 问题描述 报错信息如下: Traceback (most recent call last): File "C:\Pyt ...
- linux shell 脚本攻略学习15--如何只列出目录,如何快速切换目录
工作中经常遇到关于目录方面的问题,例如,如何只列出当前目录下的所有目录,以及如何快速高效的切换目录,而不需要使用鼠标,下面将简单介绍关于这两方面的解决方案: 一.如何只列出目录? 看似简单的任务,其实 ...
- Lua初学
Lua很火啊,而且跟C,c++可以无缝结合,表示很给力,算是我的第三门语言吧,哈哈! 在官网上下载了源码了,和windows版的,表示编译器也很给力,直接可以用SciTE就可以写代码了. a = 1; ...