下面的例子是简单的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)的更多相关文章

  1. Python并发编程-SocketServer多线程版

    #server.py import socket from threading import Thread def chat(conn): conn.send(b'hello') msg = conn ...

  2. Python并发编程理论篇

    Python并发编程理论篇 前言 其实关于Python的并发编程是比较难写的一章,因为涉及到的知识很复杂并且理论偏多,所以在这里我尽量的用一些非常简明的语言来尽可能的将它描述清楚,在学习之前首先要记住 ...

  3. Python并发编程__多进程

    Python并发编程_多进程 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大 ...

  4. Python并发编程的几篇文章

    Python几种并发实现方案的性能比较 http://www.elias.cn/Python/PyConcurrency?from=Develop.PyConcurrency python并发编程 h ...

  5. Python并发编程之深入理解yield from语法(八)

    大家好,并发编程 进入第八篇. 直到上一篇,我们终于迎来了Python并发编程中,最高级.最重要.当然也是最难的知识点--协程. 当你看到这一篇的时候,请确保你对生成器的知识,有一定的了解.当然不了解 ...

  6. 自学Python之路-Python并发编程+数据库+前端

    自学Python之路-Python并发编程+数据库+前端 自学Python之路[第一回]:1.11.2 1.3

  7. Python并发编程二(多线程、协程、IO模型)

    1.python并发编程之多线程(理论) 1.1线程概念 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程(流水线的工作需要电源,电源就相当于 ...

  8. Python并发编程一(多进程)

    1.背景知识(进程.多道技术) 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一 ...

  9. 《转载》Python并发编程之线程池/进程池--concurrent.futures模块

    本文转载自Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mult ...

  10. Python并发编程系列之多线程

    1 引言 上一篇博文详细总结了Python进程的用法,这一篇博文来所以说Python中线程的用法.实际上,程序的运行都是以线程为基本单位的,每一个进程中都至少有一个线程(主线程),线程又可以创建子线程 ...

随机推荐

  1. python2和python3网络访问包

    python3 import http.client import urllib.parse python2 import httplib import urllib

  2. kube-proxy源代码分析

    摘要:假设你对kube-proxy的工作原理有一定的了解.本文基于kubernetes v1.5代码对kube-proxy的源代码文件夹结构进行了分析,并以iptables mode为例进行了完整流程 ...

  3. JQuery EasyUI学习笔记

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6690888.html  简介与准备 jQuery EasyUI 是一个基于 jQuery 的框架,集成了各种用 ...

  4. Java多线程之线程的状态以及线程间协作通信导致的线程状态转换

      转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561589.html  一:线程的状态以及变化图 Java中线程中状态可分为五种:New(新建状态),Ru ...

  5. 2、传统的线程互斥synchronized

    synchronized使用之基本原则: synchronized可以锁方法,也可以锁代码片段,但要实现互斥的基本就是在想要互斥的代码上加”同一把锁“,也就是同一个对象,也就是用==判断等于true的 ...

  6. python模块之JSON

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #python模块之JSON #1.JSON #JSON表示的对象就是标准的JavaScript语言的对象 # ...

  7. Office2013中文激活版

    国内的WPS专业版也是很不错的,习惯的Office.office2013很不错的办公利器 00.PPT 01.Word 02.Excel Download: 链接: https://pan.baidu ...

  8. ACE的源码划分

    前几篇文章也提到过,ACE的所有源文件和头文件都杂乱堆在了ACE_wrappers/ace目录下.这样的代码组织方式给学习ACE带来了很大的困难,很多朋友在看到ace目录下庞大的代码的时候,几乎就失去 ...

  9. Uploadify in ASP.Net

    和分页类似,文件上传是web开发标配的技能之一.下面介绍Uploadify的配置和使用. 一.配置 首先到Uploadify官网下载,然后在项目中添加相应引用.前台代码如下: 1.jquery.js2 ...

  10. data1是字符串?需要加上引号

    07-22 15:55:29.832: E/AndroidRuntime(23914): FATAL EXCEPTION: main 07-22 15:55:29.832: E/AndroidRunt ...