最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python基于socket模擬實(shí)現(xiàn)ssh遠(yuǎn)程執(zhí)行命令

 更新時(shí)間:2020年12月05日 09:34:07   作者:彩虹然  
這篇文章主要介紹了python基于socket模擬實(shí)現(xiàn)ssh遠(yuǎn)程執(zhí)行命令,幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下

一、subprocess.Popen()

subprocess模塊定義了一個(gè)類: Popen

類原型:

class subprocess.Popen( args, 
  bufsize = 0, 
  executable = None, 
  stdin = None, 
  stdout = None, 
  stderr = None, 
  preexec_fn = None, 
  close_fds = False, 
  shell = False, 
  cwd = None, 
  env = None, 
  universal_newlines = False, 
  startupinfo = None, 
  creationflags = 0)

我們只需要關(guān)注其中幾個(gè)參數(shù):

  • args:

args參數(shù)。可以是一個(gè)字符串,可以是一個(gè)包含程序參數(shù)的列表。要執(zhí)行的程序一般就是這個(gè)列表的第一項(xiàng),或者是字符串本身。

  • shell=True:

在Linux下,當(dāng)shell=True時(shí),如果arg是個(gè)字符串,就使用shell來解釋執(zhí)行這個(gè)字符串。如果args是個(gè)列表,則第一項(xiàng)被視為命令,其余的都視為是給shell本身的參數(shù)。也就是說,等效于:
subprocess.Popen(['/bin/sh', '-c', args[0], args[1], ...])

  • stdin stdout和stderr:

stdin stdout和stderr,分別表示子程序的標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤。可選的值有PIPE或者一個(gè)有效的文件描述符(其實(shí)是個(gè)正整數(shù))或者一個(gè)文件對(duì)象,還有None。如果是PIPE,則表示需要?jiǎng)?chuàng)建一個(gè)新的管道,如果是None,不會(huì)做任何重定向工作,子進(jìn)程的文件描述符會(huì)繼承父進(jìn)程的。另外,stderr的值還可以是STDOUT,表示子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤也輸出到標(biāo)準(zhǔn)輸出。

二、粘包現(xiàn)象

所謂粘包問題主要還是因?yàn)榻邮辗讲恢老⒅g的界限,還有系統(tǒng)緩存區(qū)的問題,時(shí)間差的原因,不知道一次性提取多少字節(jié)的數(shù)據(jù)所造成的。

須知:只有TCP有粘包現(xiàn)象,UDP永遠(yuǎn)不會(huì)粘包

粘包不一定會(huì)發(fā)生,如果發(fā)生了:1.可能是在客戶端已經(jīng)粘了;2.客戶端沒有粘,可能是在服務(wù)端粘了

緩沖區(qū)的作用:存儲(chǔ)少量數(shù)據(jù)

如果你的網(wǎng)絡(luò)出現(xiàn)短暫的異?;蛘卟▌?dòng),接收數(shù)據(jù)就會(huì)出現(xiàn)短暫的中斷,影響你的下載或者上傳的效率。但是,緩

沖區(qū)解決了上傳下載的傳輸效率的問題,帶來了黏包問題。

收發(fā)的本質(zhì):不一定是一收一發(fā)

三、為什么出現(xiàn)粘包?

1,接收方?jīng)]有及時(shí)接收緩沖區(qū)的包,造成多個(gè)包接收(客戶端發(fā)送了一段數(shù)據(jù),服務(wù)端只收了一小部分,服務(wù)端下次再收的時(shí)候還是從緩沖區(qū)拿上次遺留的數(shù)據(jù),產(chǎn)生粘包)recv會(huì)產(chǎn)生黏包(如果recv接受的數(shù)據(jù)量(1024)小于發(fā)送的數(shù)據(jù)量,第一次只能接收規(guī)定的數(shù)據(jù)量1024,第二次接收剩余的數(shù)據(jù)量)

2,發(fā)送端需要等緩沖區(qū)滿才發(fā)送出去,造成粘包(發(fā)送數(shù)據(jù)時(shí)間間隔很短,數(shù)據(jù)也很小,會(huì)合到一起,產(chǎn)生粘包)send 也可能發(fā)生粘包現(xiàn)象。(連續(xù)send少量的數(shù)據(jù)發(fā)到輸出緩沖區(qū),由于緩沖區(qū)的機(jī)制,也可能在緩沖區(qū)中不斷積壓,多次寫入的數(shù)據(jù)被一次性發(fā)送到網(wǎng)絡(luò))

出現(xiàn)粘包現(xiàn)象的代碼實(shí)例

server. py

import socket
import subprocess

# 建立
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# 綁定
phone.bind(('127.0.0.1', 8081))

# 監(jiān)聽
phone.listen(5)

# 通信循環(huán)
while True:
  # 接收客戶端連接請(qǐng)求
  conn, client_addr = phone.accept()
  while True:
    # 接收客戶端數(shù)據(jù)/命令
    cmd = conn.recv(1024)
    if not cmd:
      break
    # 創(chuàng)建管道
    obj = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout = obj.stdout.read()
    stderr = obj.stderr.read()
    # 向客戶端發(fā)送數(shù)據(jù)
    conn.send(stdout)
    conn.send(stderr)
  # 結(jié)束連接
  conn.close()

# 關(guān)閉套接字
phone.close()

client. py

import socket

# 建立
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 連接
phone.connect(('127.0.0.1', 8081))
while True:
  cmd = input('>>> ').strip()
  if not cmd:
    continue
  if cmd == 'quit':
    break
  # 給服務(wù)端發(fā)送數(shù)據(jù)/命令
  phone.send(cmd.encode('utf-8'))
  # 接收服務(wù)端數(shù)據(jù)/命令
  data = phone.recv(1024)
  print(data.decode('utf-8'))

# 關(guān)閉套接字
phone.close()

粘包現(xiàn)象運(yùn)行結(jié)果

可以觀察到執(zhí)行兩次ls命令后,服務(wù)端返回的仍然是ifconfig命令的結(jié)果,最后一次ls命令的末尾才出現(xiàn)ls命令返回的部分結(jié)果

四、解決粘包問題的代碼實(shí)例
server. py

import socket
import subprocess
import json
import struct

# 建立
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# 綁定
phone.bind(('127.0.0.1', 8081))

# 監(jiān)聽
phone.listen(5)

# 通信循環(huán)
while True:
  # 接收客戶端連接請(qǐng)求
  conn, client_addr = phone.accept()
  while True:
    # 接收客戶端數(shù)據(jù)/命令
    cmd = conn.recv(1024)
    if not cmd:
      continue
    # 創(chuàng)建數(shù)據(jù)流管道
    obj = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout = obj.stdout.read()
    stderr = obj.stderr.read()
    # 向客戶端發(fā)送數(shù)據(jù)

    # 解決粘包問題
    # 1.制作固定長(zhǎng)度的報(bào)頭
    header_dic = {
      'filename': 'a.txt',
      'total_size': len(stdout)+len(stderr)
    }
    # 序列化報(bào)頭
    header_json = json.dumps(header_dic) # 序列化為byte字節(jié)流類型
    header_bytes = header_json.encode('utf-8') # 編碼為utf-8(Mac系統(tǒng))
    # 2.先發(fā)送報(bào)頭的長(zhǎng)度
    # 2.1 將byte類型的長(zhǎng)度打包成4位int
    conn.send(struct.pack('i', len(header_bytes)))
    # 2.2 再發(fā)報(bào)頭
    conn.send(header_bytes)
    # 2.3 再發(fā)真實(shí)數(shù)據(jù)
    conn.send(stdout)
    conn.send(stderr)
  # 結(jié)束連接
  conn.close()

# 關(guān)閉套接字
phone.close()

client. py

import socket
import struct
import json

# 建立
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 連接
phone.connect(('127.0.0.1', 8081))
while True:
  cmd = input('>>> ').strip()
  if not cmd:
    continue
  if cmd == 'quit':
    break
  # 給服務(wù)端發(fā)送命令
  phone.send(cmd.encode('utf-8'))
  # 接收服務(wù)端數(shù)據(jù)

  # 1.先收?qǐng)?bào)頭長(zhǎng)度
  obj = phone.recv(4)
  header_size = struct.unpack('i', obj)[0]
  # 2.收?qǐng)?bào)頭
  header_bytes = phone.recv(header_size)
  # 3.從報(bào)頭中解析出數(shù)據(jù)的真實(shí)信息(報(bào)頭字典)
  header_json = header_bytes.decode('utf-8')
  header_dic = json.loads(header_json)
  total_size = header_dic['total_size']
  # 4.接受真實(shí)數(shù)據(jù)
  recv_size = 0
  recv_data = b''
  while recv_size < total_size:
    res = phone.recv(1024)
    recv_data += res
    recv_size += len(res)
  print(recv_data.decode('utf-8'))

# 關(guān)閉套接字
phone.close()

以上就是python基于socket模擬實(shí)現(xiàn)ssh遠(yuǎn)程執(zhí)行命令的詳細(xì)內(nèi)容,更多關(guān)于python基于socket實(shí)現(xiàn)ssh遠(yuǎn)程執(zhí)行命令的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

以上就是python基于socket模擬實(shí)現(xiàn)ssh遠(yuǎn)程執(zhí)行命令的詳細(xì)內(nèi)容,更多關(guān)于python socket的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python入門教程(二十)Python的Lambda表達(dá)式

    Python入門教程(二十)Python的Lambda表達(dá)式

    這篇文章主要介紹了Python入門教程(二十)Python的Lambda表達(dá)式,lambda表達(dá)式是一行的函數(shù)。它們?cè)谄渌Z言中也被稱為匿名函數(shù),lambda表達(dá)式非常有用,可以讓代碼簡(jiǎn)單,簡(jiǎn)潔,需要的朋友可以參考下
    2023-04-04
  • Python Pexpect庫的簡(jiǎn)單使用方法

    Python Pexpect庫的簡(jiǎn)單使用方法

    這篇文章主要介紹了Python Pexpect庫的簡(jiǎn)單使用方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • 利用python繪制帶有時(shí)間線的柱狀圖

    利用python繪制帶有時(shí)間線的柱狀圖

    這篇文章主要為大家詳細(xì)介紹了如何使用python繪制出帶有時(shí)間線的柱狀圖,文中的示例代碼講解的非常詳細(xì),具有一定的學(xué)習(xí)與借鑒價(jià)值,需要的可以參考一下
    2023-07-07
  • Python中常用的內(nèi)置方法

    Python中常用的內(nèi)置方法

    今天小編就為大家分享一篇關(guān)于Python中常用的內(nèi)置方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • python中的多cpu并行編程

    python中的多cpu并行編程

    這篇文章主要介紹了python中的多cpu并行編程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 解決win64 Python下安裝PIL出錯(cuò)問題(圖解)

    解決win64 Python下安裝PIL出錯(cuò)問題(圖解)

    這篇文章主要介紹了解決win64 Python下安裝PIL出錯(cuò)問題,文中的解決方法也很簡(jiǎn)單,需要的朋友參考下吧
    2018-09-09
  • 生成Jupyter Lab快捷方式的小技巧

    生成Jupyter Lab快捷方式的小技巧

    這篇文章主要介紹了生成Jupyter Lab快捷方式的小技巧,操作迅猛,花費(fèi)時(shí)間少,步驟詳細(xì),有需要的朋友可以參考下,希望可以對(duì)廣大讀者朋友有所幫助
    2021-09-09
  • Python操作SQLite簡(jiǎn)明教程

    Python操作SQLite簡(jiǎn)明教程

    這篇文章主要介紹了Python操作SQLite簡(jiǎn)明教程,簡(jiǎn)單明了的入門教程,包含連接、建表、增刪修查等例子,需要的朋友可以參考下
    2014-07-07
  • python模塊離線安裝方式

    python模塊離線安裝方式

    這篇文章主要介紹了python模塊離線安裝方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • python屬于哪種語言

    python屬于哪種語言

    在本篇內(nèi)容里小編給大家整理的是一篇關(guān)于python屬于哪種語言的一篇基礎(chǔ)內(nèi)容文章,有興趣的朋友們可以參考下。
    2020-08-08

最新評(píng)論

海口市| 双辽市| 凤阳县| 彩票| 金堂县| 旬阳县| 罗江县| 通榆县| 鹿泉市| 新乡县| 阿合奇县| 高雄市| 临清市| 青海省| 平昌县| 读书| 南郑县| 长乐市| 山阳县| 兖州市| 湖州市| 师宗县| 会昌县| 左贡县| 金山区| 洞头县| 周至县| 吴桥县| 吉林市| 利辛县| 贵阳市| 宜川县| 长武县| 庆城县| 高陵县| 曲水县| 雷波县| 雅安市| 丽江市| 万宁市| 新乡县|