远程执行命令

先来学习一个新模块 , 一会用到的..

新模块: subprocess
执行系统命令
r = subprocess.Popen('ls',shell=True,stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
subprocess.Popen(a,b,c,d)
a: 要执行的系统命令(str)
b: shell = True 表示确定我当前执行的命令为系统命令
c: 表示正确信息的输出管道
d: 表示错误信息的输出管道

下边直接上代码,一看就懂.  TCP的

import socket
import subprocess
sk = socket.socket()
sk.bind(('127.0.0.1',9090))
sk.listen()
conn,addr = sk.accept()
while 1:
cmd = conn.recv(1024).decode('utf-8')
res = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
std_out = res.stdout.read()# 读取正确的返回信息
std_err = res.stderr.read()# 读取错误的返回信息 if std_out:
conn.send(std_out)
else:
conn.send(std_err) conn.close()
sk.close()

远程服务端

import socket
sk = socket.socket()
sk.connect_ex(('127.0.0.1',9090))
while 1:
cmd = input('请输入一个命令>>>')
sk.send(cmd.encode('utf-8'))
print(sk.recv(204800000).decode('gbk')) sk.close()

远程客户端

就是引用了一个模块的功能,其他的还是简单的收发功能.

res=subprocess.Popen(cmd.decode('utf-8'),
shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE) 的结果的编码是以当前所在的系统为准的,如果是windows,那么res.stdout.read()读出的就是GBK编码的,在接收端需要用GBK解码 且只能从管道里读一次结果 注意

--------------------粘包---------------------------

 UDP不会发生黏包--------

UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务。
不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,
在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。
即面向消息的通信是有消息保护边界的。
对于空消息:tcp是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住,
而udp是基于数据报的,即便是你输入的是空内容(直接回车),也可以被发送,udp协议会帮你封装上消息头发送过去。
不可靠不黏包的udp协议:udp的recvfrom是阻塞的,一个recvfrom(x)必须对唯一一个sendinto(y),收完了x个字节的数据就算完成,若是y;x数据就丢失,
这意味着udp根本不会粘包,但是会丢数据,不可靠。

补充说明:

用UDP协议发送时,用sendto函数最大能发送数据的长度为:65535- IP头(20) – UDP头(8)=65507字节。
用sendto函数发送数据时,如果发送数据长度大于该值,则函数会返回错误。(丢弃这个包,不进行发送) 用TCP协议发送时,由于TCP是数据流协议,因此不存在包大小的限制(暂不考虑缓冲区的大小),这是指在用send函数时,数据长度参数不受限制。
而实际上,所指定的这段数据并不一定会一次性发送出去,如果这段数据比较长,会被分段发送,如果比较短,可能会等待和下一次数据一起发送。

总结

黏包现象只发生在tcp协议中:

1.从表面上看,黏包问题主要是因为发送方和接收方的缓存机制、tcp协议面向流通信的特点。

2.实际上,主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的

解决方案------------

我们可以借助一个模块,这个模块可以把要发送的数据长度转换成固定长度的字节。这样客户端每次接收消息之前只要先接受这个固定长度字节的内容看一看接下来要接收的信息大小,那么最终接受的数据只要达到这个值就停止,就能刚好不多不少的接收完整的数据了。

文件上传解决粘包 的代码:  利用字典先传过去文件大小即可....

import socket
import json
import struct
sk = socket.socket()
sk.bind(('127.0.0.1',9090))
sk.listen()
conn,addr = sk.accept()
dic_size = conn.recv(4)# 先接受4字节长度的一个bytes, 代表字典的大小
dic_size = struct.unpack('i',dic_size)[0]# 将这个特殊的bytes转变成原数字
dic_str = conn.recv(dic_size).decode('utf-8')# 根据字典大小去获取字典,以免和底下获取文件内容发生粘包
dic = json.loads(dic_str)# 反序列化 得到字典 opt filename filesize
if dic['opt'] == 'upload':
'''接收文件'''
filename = ''+dic['filename']# 将文件名字修改,防止重名
with open(filename,'wb') as f:
while dic['filesize']:
content = conn.recv(1024)
f.write(content)
dic['filesize'] -= len(content)
elif dic['opt'] == 'download':
'''给客户端传输文件'''
conn.close()
sk.close()

文件上传 服务端

import socket
import os
import json import struct sk = socket.socket()
sk.connect(('127.0.0.1',9090))
l = ['upload','download']
for i,v in enumerate(l):
print(i+1,v)
dic = {'opt':None,'filename':None,'filesize':None}
while 1:
opt = input("请输入功能选项>>>")# 客户要执行的操作选项
if opt == '':
'''upload'''
file_dir = input('请输入文件路径>>>')# 'E:/sylar/python_workspace/day34/作业/时间同步机制_client.py'
file_name = os.path.basename(file_dir)# 获取文件名字
file_size = os.path.getsize(file_dir)# 获取文件大小
dic['opt'] = l[int(opt)-1]
dic['filename'] = file_name
dic['filesize'] = file_size
dic_str = json.dumps(dic)# 将字典序列化成一个字符串形式的字典
dic_size = len(dic_str)# 获取字典的大小
ds = struct.pack('i',dic_size)# 把一个小于21.3E的一个数字转变成一个4字节长度的bytes
sk.send(ds + dic_str.encode('utf-8'))# 发送给服务器
with open(file_dir,'rb') as f:
while file_size:
content = f.read(1024)# 文件内容
sk.send(content)
file_size -= len(content)
elif opt == '':
'''download'''
pass
else:
print('有误') sk.close()

文件上传 客户端

收发概括

python 网络编程(远程执行命令与粘包)的更多相关文章

  1. 网络编程之模拟ssh远程执行命令、粘包问题 、解决粘包问题

    目录 模拟ssh远程执行命令 服务端 客户端 粘包问题 什么是粘包 TCP发送数据的四种情况 粘包的两种情况 解决粘包问题 struct模块 解决粘包问题 服务端 客户端 模拟ssh远程执行命令 服务 ...

  2. Python_编写UDP通信编解码类、文件的上传、远程执行命令、黏包

    1.UDP通信编解码类 (1) 类 # ------------------UDP通信解码编码类------------------------ from socket import * class ...

  3. python之paramiko 远程执行命令

    有时会需要在远程的机器上执行一个命令,并获得其返回结果.对于这种情况,python 可以很容易的实现. 1 .工具 Python paramiko 1) Paramiko模块安装 在Linux的Ter ...

  4. Python 简单的远程执行命令

    client端执行命令,server端返回命令结果 # server 端 import socket, subprocess sk = socket.socket() address=('127.0. ...

  5. python实现批量远程执行命令及批量上传下载文件

    #!/usr/bin/env python # -*- coding: utf- -*- # @Time : // : # @Author : xuxuedong # @Site : # @File ...

  6. 【游戏开发】网络编程之浅谈TCP粘包、拆包问题及其解决方案

    引子 现如今手游开发中网络编程是必不可少的重要一环,如果使用的是TCP协议的话,那么不可避免的就会遇见TCP粘包和拆包的问题,马三觉得haifeiWu博主的 TCP 粘包问题浅析及其解决方案 这篇博客 ...

  7. TCP 远程执行CMD (解决粘包问题) 代码

    服务端 from socket import * import subprocess,json,struct server= socket(AF_INET,SOCK_STREAM) server.bi ...

  8. Python网络编程基础 struct模块 解决黏包问题 FTP

    struct模块 解决黏包问题 FTP

  9. 网络编程socket模块subprocess模块 粘包的解决

    什么是socket? tcp 可靠地面向连接协议 udp 不可靠的,无连接的服务,传送效率高

随机推荐

  1. 【luogu P1962 斐波那契数列】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1962 给你篇dalao的blog自己看吧,把矩阵快速幂的板子一改就OK #include <algor ...

  2. C#多线程最简单Demo

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  3. Android学习笔记_24_多媒体MediaPlayer对象之音乐播放器与SoundPool声音池

    一.MediaPlayer对象常用方法介绍: MediaPlayer mediaPlayer = new MediaPlayer(); if (mediaPlayer.isPlaying()) { m ...

  4. 使用带有对象的data-ng-bind

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  5. Mac 使用问题

    Mac 使用 Mac改变系统截图存储位置 鼠标在屏幕中间上下滚动时,有时反应不灵敏: 看看偏好设置-> 鼠标 -> 跟踪速度或者手势部分是否有哪里设置不当: 考虑重新开启鼠标鼠标底部有一个 ...

  6. JavaScript的原型(prototype、__proto__、constructor)

    构造函数:function Foo() {}; 实例对象: let f1 = new Foo; let o1 = new Foo; 一般函数都有prototype属性,除了window.Math和Fu ...

  7. linux上部署redis实现与Python上的redis交互(有坑)

    1.概念 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件 2.linux安装redis 2.1yum源安装redis(不推荐) #前提得配置好阿里 ...

  8. swift计算label动态宽度和高度

    swift计算label动态宽度和高度 func getLabHeigh(labelStr:String,font:UIFont,width:CGFloat) -> CGFloat { let ...

  9. C++ primer 练习9.52 适配器stack 中缀表达式

    //调试环境 VS2015//本人菜鸟一枚,不喜勿喷! 谢谢!!!//主要思想引自  http://www.cnblogs.com/dolphin0520/p/3708602.html//主要代码引自 ...

  10. P1330 封锁阳光大学 DFS+染色

    题目链接:https://www.luogu.org/problemnew/show/P1330 这个题有意思,如果能想到染色,就会很简单,但若想不到就很麻烦 要想把一条边封锁,就必须且只能占据这条边 ...