模拟ssh远程执行命令

服务端

import socket
import subprocess server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('127.0.0.1', 8000)) server.listen(5) print('strat...')
while True: conn, client_addr = server.accept() # 可以建立多个来连接 while True:
cmd = conn.recv(1024) pipeline = subprocess.Popen(cmd.decode('utf-8'), # 输入的cmd命令
shell=True, # 通过shell运行
stderr=subprocess.PIPE, # 把错误输出放入管道,以便打印
stdout=subprocess.PIPE) # 把正确输出放入管道,以便打印 stdout = pipeline.stdout.read()
stderr = pipeline.stderr.read() conn.send(stdout + stderr) conn.close()
server,close()

客户端

from socket import *

client = socket(AF_INET, SOCK_STREAM)

client.connect(('127.0.0.1', 8000))

while True:
data = input('请输入命令>>>') client.send(data.encode('utf-8')) msg = client.recv(1024) print(msg.decode('gbk')) # 与操作系统在交互,解码使用gbk解码 client.close()

粘包问题

什么是粘包

注意:只有TCP协议会有粘包问题,UDP协议不会粘包

  • socket收发消息原理

因为服务端一次性把数据给出来了,但是客户端每次只能接受1024个字节的数据,如果数据量较大,服务端就需要一个缓存来存放数据,然后等待客户端一段一段的接收数据;

但是如果此时客户端又发出一个需求,服务端接收到需求,把数据再次丢入缓存,此时服务端里面的缓存里还有数据,则就会直接接在第一次数据后面,等客户端接受时,并不会分辨第一次和第二次的数据,直接又拿1024个字节,这样就会发生第一次数据后面又第二次请求的数据,这就是粘包。

  • 所谓的粘包问题主要就是因为接收端不知道消息的界限,不知道一次性取多少个字节的数据造成的。

TCP发送数据的四种情况

假设客户端分别发送了两个数据包D1和D2给服务端,由于服务端一次读取到的字节数是不确定的,故可能存在以下4种情况。

  1. 服务端分两次读取到了两个独立的数据包,分别是D1和D2,没有粘包和拆包;
  2. 服务端一次接收到了两个数据包,D1和D2粘合在一起,被称为TCP粘包;
  3. 服务端分两次读取到了两个数据包,第一次读取到了完整的D1包和D2包的部分内容,第二次读取到了D2包的剩余内容,这被称为TCP拆包;
  4. 服务端分两次读取到了两个数据包,第一次读取到了D1包的部分内容D1_1,第二次读取到了D1包的剩余内容D1_2和D2包的整包。

粘包的两种情况

  1. 发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包)

  2. 接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)

解决粘包问题

struct模块

struct 模块可以把数据型打包成一个4-8 bytes的数据

import struct

data = struct.pack('i', 24789)  # 压缩

print(data)
print(len(data))
b'\xd5`\x00\x00'
4
import struct

data = struct.pack('i', 24789)

res = struct.unpack('i', data)
print(res[0])
24789

解决粘包问题

解决粘包问题的核心就是:为字节流加上自定义固定长度报头,报头中包含字节流长度,然后一次send到对端,对端在接收时,先从缓存中取出定长的报头,然后再取真实数据。

服务端

import socket
import struct
import subprocess server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('127.0.0.1', 8000)) server.listen(5) print('strat...')
while True: conn, client_addr = server.accept() # 可以建立多个来连接 while True:
cmd = conn.recv(1024) pipeline = subprocess.Popen(cmd.decode('utf-8'), # 输入的cmd命令
shell=True, # 通过shell运行
stderr=subprocess.PIPE, # 把错误输出放入管道,以便打印
stdout=subprocess.PIPE) # 把正确输出放入管道,以便打印 stdout = pipeline.stdout.read()
stderr = pipeline.stderr.read() length = len(stdout) + len(stderr) # 1、先把报头的长度len(header_bytes)打包成4个bytes,然后发送
conn.send(struct.pack('i', length))
# 2、发送真实数据
conn.send(stdout + stderr) conn.close()
server,close()

客户端

import struct
from socket import * client = socket(AF_INET, SOCK_STREAM) client.connect(('127.0.0.1', 8000)) while True:
data = input('请输入命令>>>') client.send(data.encode('utf-8')) res = client.recv(4) msg = client.recv(struct.unpack('i', res)[0]) print(msg.decode('gbk')) # 与操作系统在交互,解码使用gbk解码 client.close()

网络编程之模拟ssh远程执行命令、粘包问题 、解决粘包问题的更多相关文章

  1. 网络编程 - 1.简单的套接字通信/2.加上通信循环/3.bug修复/4.加上链接循环/5.模拟ssh远程执行命令

    1.简单的套接字通信 服务端 ''' 服务端 接电话 客户端 打电话 1.先启动服务端 2.服务端有两种套接字 1.phone 用来干接收链接的 2.conn 用来干收发消息的 ''' import ...

  2. 模拟ssh远程执行命令,粘包问题,基于socketserver实现并发的socket

    06.27自我总结 1.模拟ssh远程执行命令 利用套接字编来进行远程执行命令 服务端 from socket import * import subprocess server = socket(A ...

  3. 模拟ssh远程执行命令

    目录 一.服务端 二.客户端 一.服务端 from socket import * import subprocess server = socket(AF_INET, SOCK_STREAM) se ...

  4. 利用scp 远程上传下载文件/文件夹和ssh远程执行命令

    利用scp传输文件 1.从服务器下载文件scp username@servername:/path/filename /tmp/local_destination例如scp codinglog@192 ...

  5. 解决SSH远程执行命令找不到环境变量的问题

    通过SSH执行远程主机的命令或脚本时,经常会出现找不到自定义环境变量的问题.但是,如果通过SSH登录远程主机,然后再执行相同的命令或脚本,那么此时执行又是成功的.两种相似的方法,得到的结果却截然不同, ...

  6. ssh远程执行命令使用明文密码

    经过不懈的搜索终于找到ssh远程执行命令使用明文密码使用sshpass. 例子: sshpass -p "sequoiadb" ssh root@localhost "l ...

  7. SSH远程执行命令环境变量问题

    SSH命令格式 usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D [bind_address: ...

  8. [转帖]ssh 远程执行命令

    ssh 远程执行命令 https://www.cnblogs.com/youngerger/p/9104144.html SSH 是 Linux 下进行远程连接的基本工具,但是如果仅仅用它来登录那可是 ...

  9. 使用ssh远程执行命令批量导出数据库到本地

    前天正在跟前端的同事调试功能.服务器开好,模拟的玩家登录好,就在倒计时.这时突然运营的同事跑过来说要统计几个服务器玩家的一些情况,也就是需要从几个服的数据库导出部分玩家的数据.好吧,我看了一下时间,1 ...

随机推荐

  1. Python面试题(1)

    1.如何反向迭代一个序列 #如果是一个list,最快的方法使用reversetempList = [1,2,3,4]tempList.reverse()for x in tempList:    pr ...

  2. tf–idf算法解释及其python代码

    tf–idf算法python代码实现 这是我写的一个tf-idf的简单实现的代码,我们知道tfidf=tf*idf,所以可以分别计算tf和idf值在相乘,首先我们创建一个简单的语料库,作为例子,只有四 ...

  3. opencart按重量配送如何设置

    OpenCart中基于重量的配送模块让你使用自己的价格折算表来决定配送价格.可以基于不同的重量允许设置价格范围,重量和价格的格式如下:weight(重量1):cost(价格1), weight(重量2 ...

  4. 06-numpy-笔记-shape

    shape 是返回 np.mat 的形状的. 1. 作为 mat 的成员变量,a.shape 2. 作为 np 的成员函数,np.shape >>> import numpy as ...

  5. redhat quay 安装试用

    最近redhat 开源了quay 容器镜像管理平台,参考官方文档跑的时候需要订阅,各种不好使,然后就自己基于源码构建了 一个镜像(使用官方的dockerfile,构建出来的太大了1.9G 以及push ...

  6. IE与标准浏览器对事件处理的区别?(监听、阻止冒泡、阻止默认等)

    谷歌 IE:监听:addEventListener   attachEvent--------要在事件名称前面加on解绑:removeEventListener      detachEvent--- ...

  7. Koa帮我们做了什么

    整理web渲染思路,与KOA作比较 1.开启服务器并监听端口,注册监听事件 // 原生 let http = require('http') const server = http.createSer ...

  8. VUE温习:内存泄漏、Vue.$set、key作用与虚拟diff算法

    一.内存泄漏 1.指令绑定了事件,却没有解绑事件,容易产生内存泄漏.(曾经遇到过的案例) 2.v-if指令产生内存泄漏,比如v-if删除了父级元素,却没有删除父级元素里的dom片段 3.跳转到别的路由 ...

  9. rabbitmq安装集群

    centos 7.3 64 172.18.39.241 k8s-mini-241172.18.39.242 k8s-mini-242172.18.39.243 k8s-master-243 vim / ...

  10. 2018-2019-2 20165315《网络对抗技术》Exp7 网络欺诈防范

    2018-2019-2 20165315<网络对抗技术>Exp7 网络欺诈防范 一.实验内容 本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法.具体实践有 简单应 ...