远程执行模块和黏包 socketserve hamc模块验证合法性
一.远程执行模块:subprocess
能执行操作系统的命令的功能
ret=subprocess.Popen("dir", #要执行的命令 shell=True, # 表示要执行的是一条系统命令 stdout=subprocess.PIPE, # 存储执行结果的正常信息 stderr=subprocess.PIPE) # 存储执行结果的错误信息#读出的内容是bytes类型print("stdout: ",ret.stdout.read().decode("gbk")) #在windows环境下转换成gbk格式。在linux环境下转换成utf-8print("stderr: ",ret.stderr.read().decode("gbk"))server端
import socket import subprocess sk=socket.socket() sk.bind(("127.0.0.1",9000)) sk.listen() conn,addr=sk.accept() while True:cmd=input("请输入操作命令:")if cmd == "q":conn.send(cmd.encode("utf-8"))breakconn.send(cmd.encode("utf-8"))print('stdout : ', conn.recv(1024).decode('gbk')) #只有这个接收的话会丢包。接收不完整。剩余的会被另一条命令接收到print('stderr : ', conn.recv(1024).decode('gbk')) conn.close() sk.close()
View Code
client端
import socket import subprocess sk=socket.socket() sk.connect(("127.0.0.1",9000)) while True:cmd=sk.recv(1024).decode("utf-8")if cmd == "q":breakret=subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)sk.send(ret.stdout.read())sk.send(ret.stderr.read()) sk.close()
View Code
二.黏包
只有TCP有粘包现象,UDP永远不会粘包
1.黏包的概念:
同时执行多条命令之后,得到的结果很可能只有一部分
在执行其他命令的时候又接收到之前执行的另外一部分结果,这种现象就是黏包。
2.产生黏包的原因:
1.从表面上看,黏包问题主要是因为发送方和接收方的缓存机制、tcp协议面向流通信的特点。2.实际上,主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的
3.发生黏包的两种情况:
1.发送方的缓存机制:发送端需要等缓冲区满才发送出去发送端多次send间隔较短,并且数据量较小,tcp会通过Nagle算法,封装成一个包,发送到接收端,接收端不知道这个包由几部分组成,所以就会产生粘包。2.接收方的缓存机制数据量发送的大,接收端接收的小,再接一次,会出现上次没有接收完成的数据。就会出现粘包
4.tcp协议的拆包机制,面向流的通信特点和Nagle算法
当发送端缓冲区的长度大于网卡的MTU时(网络上传送的最大数据包)tcp会将这次发送的数据拆成几个数据包发送出去发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法)将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包
tcp和udp的总结
TCP是面向连接的,面向流的,提供高可靠性服务对于空消息:tcp是基于数据流的,于是收发的消息不能为空tcp的协议数据不会丢,没有收完包,下次接收,会继续上次继续接收.数据是可靠的,但是会粘包UDP是无连接的,面向消息的,提供高效率服务UDP支持的是一对多的模式,不会使用块的合并优化算法udp是基于数据报的,即便是你输入的是空内容(直接回车),也可以被发送udp的recvfrom是阻塞的,一个recvfrom必须对唯一一个sendintoudp根本不会粘包,但是会丢数据,不可靠。
黏包的解决方案
为字节流加上自定义固定长度报头,报头中包含字节流长度,然后一次send到对端,对端在接收时,先从缓存中取出定长的报头,然后再取真实数据
struct模块
该模块可以把一个类型,如数字,转成固定长度的bytes借助struct模块,长度数字可以被转换成一个标准大小的4字节数字。可以利用这个特点来预先发送数据长度。我们还可以把报头做成字典,字典里包含将要发送的真实数据的详细信息,然后json序列化,然后用struck将序列化后的数据长度打包成4个字节(4个自己足够用了)struct.pack("i", len(str_dic)) 将长度转换成个定长(4)的bytes#unpack结果是元祖 (20,)
客户端:str_dic = json.dumps(dic).encode("utf-8")ret = struct.pack("i", len(str_dic)) # 将字典的大小转换成一个定长(4)的bytessk.send(ret + str_dic)服务端:dic_len = conn.recv(4) # 4个字节 数字的大小dic_len=struct.unpack("i",dic_len)[0]connet_str=conn.recv(dic_len).decode("utf-8")connet=json.loads(connet_str) socketserver可以使tcp实现并发编程server端
import socketserver class MyServer(socketserver.BaseRequestHandler):def handle(self):print("——————")while True:#self.request #相当于connmsg=input("<<")self.request.send(msg.encode("utf-8"))ret=self.request.recv(1024).decode("utf-8")print(ret) server=socketserver.ThreadingTCPServer(("127.0.0.1",9000),MyServer) server.serve_forever()
View Code
client端
import socket sk=socket.socket() sk.connect(("127.0.0.1",9000)) while True:ret=sk.recv(1024).decode("utf-8")if ret:if ret == "q":breakprint(ret)msg=input("<<")sk.send(msg.encode("utf-8")) sk.close()
View Code
验证客户端的合法性 hmac模块
hashlib加密后是str hamc之后为bytes
os.urandom(32) #随即产生n个字节的字符串,bytes类型可以作为随机加密key使用
server端
import socket import hmac import os sk=socket.socket() sk.bind(("127.0.0.1",9000)) sk.listen() conn,addr=sk.accept() def check_client(conn):secret_key=b"456"message=os.urandom(32) #随即产生n个字节的字符串,bytes类型可以作为随机加密key使用conn.send(message)obj=hmac.new(secret_key,message)ret=obj.digest() #加密后bytes类型msg=conn.recv(1024)if ret==msg:print('合法的客户端')return Trueelse:print('非法的客户端')return False ret=check_client(conn) while ret:msg=input("<<")conn.send(msg.encode("utf-8"))rec=conn.recv(1024).decode("utf-8")print(rec) conn.close() sk.close()
View Code
client端
import socket import hmac sk=socket.socket() sk.connect(("127.0.0.1",9000)) secret_key=b"456" msg=sk.recv(1024) obj=hmac.new(secret_key,msg) ret=obj.digest() sk.send(ret) rec=sk.recv(1024) if rec:print(rec.decode("utf-8"))while True:msg = input("<<")sk.send(msg.encode("utf-8"))msg = sk.recv(1024)print(msg.decode('utf-8')) sk.close()
View Code
转载于:https://www.cnblogs.com/zgf-666/p/8658483.html
远程执行模块和黏包 socketserve hamc模块验证合法性相关推荐
- Python_编写UDP通信编解码类、文件的上传、远程执行命令、黏包
1.UDP通信编解码类 (1) 类 1 # ------------------UDP通信解码编码类------------------------ 2 3 from socket import * ...
- python tcp黏包和struct模块解决方法,大文件传输方法及MD5校验
https://www.cnblogs.com/zaizai1573/p/10230973.html 一.TCP协议 粘包现象 和解决方案 黏包现象 让我们基于tcp先制作一个远程执行命令的程序(命令 ...
- python 模块 导入机制 模块搜索 Python包 发布python模块或程序
python 模块 python模块:以.py结尾的代码文件. 顶层文件: 程序执行入口 模块文件1 模块文件2 模块文件3 在python中一 ...
- Python攻城师的成长————网络编程(socket套接字、通信循环、链接循环、黏包问题)
今日学习目标 学习什么是socket套接字,并依靠它去处理TCP协议等网络编程问题 文章目录 今日学习目标 学习内容 一. socket套接字 1.什么是socket 2.套接字发展史及分类 3.套接 ...
- python中黏包问题的解决
python中黏包问题的解决 1.在前面我们知道tcp容易产生黏包的问题,而udp不会产生黏包的问题,但是会产生丢包的问题,tcp应用的场景很多所以黏包问题必须要解决. 1.解决黏包问题第一种方法,我 ...
- linux 带环境变量 远程执行,SSH远程执行命令环境变量问题
SSH命令格式 usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D [bind_address: ...
- saltstack(自动化运维工具)——介绍、安装、部署+远程执行
一.saltstack简介 saltstack是一个配置管理系统,能够维护预定义状态的远程节点. saltstack是一个分布式远程执行系统,用来在远程节点上执行命令和查询数据. saltstack是 ...
- TCP与UDP协议、socket套接字编程、通信相关操作(cs架构软件)、TCP黏包问题及解决思路
OSI七层协议 传输层 1.PORT协议:前面讲过 2.TCP协议与UDP协议:规定了数据传输所遵循的规则(数据传输能够遵循的协议有很多,TCP和UDP是较为常见的两个) TCP协议 基于TCP传输数 ...
- Python之黏包的解决
黏包的解决方案 发生黏包主要是因为接收者不知道发送者发送内容的长度,因为tcp协议是根据数据流的,计算机操作系统有缓存机制, 所以当出现连续发送或连续接收的时候,发送的长度和接收的长度不匹配的情况下就 ...
最新文章
- Playmaker Input篇教程之PlayMaker菜单概述
- lnmp环境切换php版本,并安装相应redis扩展
- class没有发布到tomcat_Java 类在 Tomcat 中是如何加载的?
- 同域下iframe操作时,js访问document出现拒绝访问的问题原因
- Spring Cloud微服务之父工程的创建(一)
- Unreal Engine 4 —— Pixel Depth Offset的使用心得
- 手把手叫你一台电脑配置两个Git账户
- 全新的 Discuz! Q 来了!
- 华为鸿蒙科技创新,华为、美的合作:搭载鸿蒙系统的家电来了 三大亮点
- APICloud修改最低操作系统版本要求
- 开源社群系统 ThinkSNS+ 0.7.4 版本发布
- ab压力测试及结果分析
- 《高等数学B(一)》笔记
- 马云将成全球第11大富豪,很好奇第一位是谁?
- signature=de4fefc549f99f0b0c76a2cec8e340bf,Diagnostics based on faulty signature
- 2017-12-12
- CorelDRAW x8警告您所用的软件疑似非法盗版软件,软件功能3天内将被永久停用,解决方法教程
- HTML网页设计基础期末作业——绿色化妆品网页(HTML+CSS)
- Linux下配置Samba服务器使用SMBv1或SMBv2协议
- 『译』RGB-D Salient Object Detection, A Review『译』