• socket 远程执行命令事例


    场景 :基于socket,进行远端连接以及运行命令,并把远端命令的执行结果返回。

    服务端:

     1 import socket as sk,subprocess as ss
     2 sk_obj = sk.socket(sk.AF_INET,sk.SOCK_STREAM)  #tcp协议的sock连接
     3 sk_obj.bind(('127.0.0.1',8000))
     4 sk_obj.listen(5)
     5 while True:
     6     conn,ipaddr  = sk_obj.accept()  #阻塞链接
     7     print('当前连接IP:%s '%ipaddr[0])
     8     while True:
     9         try:
    10             from_recv = conn.recv(8096)  #接收对端发来的消息
    11             if len(from_recv) == 0 :continue
    12             print("来自客户端ip:%s 消息:%s"%(ipaddr[0],from_recv))
    13             res = ss.Popen(from_recv.decode('utf-8'),shell=True,stdout=ss.PIPE,stderr=ss.PIPE)
    14             msg = res.stdout.read()
    15             if len(msg) == 0:
    16                 msg = res.stderr.read()
    17             conn.send(msg)
    18         except Exception :
    19             break
    20     conn.close()
    21 sk_obj.close()

    客户端:

     1 import socket as sk
     2 sk_obj = sk.socket(sk.AF_INET,sk.SOCK_STREAM)
     3 sk_obj.connect(('127.0.0.1',8000))
     4 
     5 while True:
     6     msg = input(">>>").strip()
     7     if len(msg) == 0 :continue
     8     sk_obj.send(msg.encode('utf-8'))
     9     data = sk_obj.recv(8096) #1024
    10     print("服务端发来消息:%s" % data.decode('gbk'))  #这里用gbk是因为windows默认系统编码格式为GBK
    11 sk_obj.close()

     client运行结果:

     1 >>>ddddd
     2 服务端发来消息:'ddddd' 不是内部或外部命令,也不是可运行的程序
     3 或批处理文件。
     4 
     5 >>>dir .
     6 服务端发来消息: 驱动器 J 中的卷没有标签。
     7  卷的序列号是 AC23-3670
     8 
     9  J:pdataday36job 的目录
    10 
    11 2017/05/04  02:03    <DIR>          .
    12 2017/05/04  02:03    <DIR>          ..
    13 2017/05/04  02:03               333 job_client.py
    14 2017/05/04  02:03               807 job_server.py
    15                2 个文件          1,140 字节
    16                2 个目录  5,046,833,152 可用字节

     server运行结果:

    1 J/day36/job/job_server.py
    2 当前连接IP:127.0.0.1 
    3 来自客户端ip:127.0.0.1 消息:b'ddddd'
    4 来自客户端ip:127.0.0.1 消息:b'dir .'
    5 当前连接IP:127.0.0.1 

     解决粘包:

     1 #coding:utf-8
     2 import socket as sk,subprocess as ss
     3 import struct
     4 import json
     5 sk_obj = sk.socket(sk.AF_INET,sk.SOCK_STREAM)
     6 sk_obj.setsockopt(sk.SOL_SOCKET,sk.SO_REUSEADDR,1)  #定制重连接
     7 sk_obj.bind(('192.168.16.132',8000))
     8 sk_obj.listen(5)
     9 while True:
    10     conn,ipaddr = sk_obj.accept()
    11     print("客户机ip:%s" %ipaddr[0])
    12     while True:
    13         try:
    14             from_recv = conn.recv(1024)
    15             print(from_recv.encode('utf-8'))
    16             if len(from_recv) == 0:break
    17             res = ss.Popen(from_recv.decode('utf-8'),
    18                            shell=True,
    19                            stdout=ss.PIPE,
    20                            stderr=ss.PIPE
    21                            )
    22 
    23             msg_stdout = res.stdout.read()
    24             msg_stderr = res.stderr.read()
    25 
    26             # 定制包头大小
    27             data_size = len(msg_stdout) + len(msg_stderr)
    28             header_dict = {'data_size': data_size}
    29             header_json = json.dumps(header_dict)
    30             header_json_bytes = header_json.encode('utf-8')
    31             head_json_bytes_len = struct.pack('i', len(header_json_bytes))
    32 
    33             # parit1 发送包头长度
    34             conn.send(head_json_bytes_len)
    35             # parit2 发送包头
    36             conn.send(header_json_bytes)
    37             # 真实消息发送
    38             conn.send(msg_stdout)
    39             conn.send(msg_stderr)
    40         except Exception:
    41             break
    42     conn.close()
    43 sk_obj.close()
    44 
    45 server端
    server端
     1 import socket as sk ,subprocess as ss
     2 import struct
     3 import json
     4 sk_obj = sk.socket(sk.AF_INET,sk.SOCK_STREAM)
     5 sk_obj.connect(('192.168.16.132',8000))#linux
     6 # sk_obj.connect(('127.0.0.1',8000))
     7 while True:
     8     msg_input = input(">>>:").strip()
     9     if not msg_input: continue
    10     sk_obj.send(msg_input.encode('utf-8'))
    11     #sk_obj.send(bytes(msg_input, encoding='utf-8'))
    12     header_struct = sk_obj.recv(4)
    13     header_bytes_len = struct.unpack('i',header_struct)[0]
    14     header_bytes = sk_obj.recv(header_bytes_len)
    15     header_json = json.loads(header_bytes.decode('utf-8'))
    16     print(header_json)
    17     header_size = header_json['data_size']
    18     recvsize  = 0
    19     recv_data = b''
    20     while recvsize < header_size:
    21         data = sk_obj.recv(1024)
    22         recvsize += len(data)
    23         recv_data += data
    24 
    25     # data = sk_obj.recv(1024)
    26     print("来自客户端消息%s"%recv_data.decode('gbk'))
    27 sk_obj.close()
    client端
     1 服务端运行结果:
     2 
     3 [root@centnfs ~]# python Ftpserver.py 
     4 客户机ip:192.168.16.132
     5 dir
     6 ls /tmp
     7 
     8 ++++++++++++++++++++++++++++++++++
     9 
    10 客户端运行结果:
    11 
    12 >>>:dir
    13 {'data_size': 280}
    14 来自客户端消息ab.sh         db        Ftpserver.py      mon_rpcd.sh    Pictures
    15 ach.sh         Desktop    initial-setup-ks.cfg  Music        Public
    16 anaconda-ks.cfg  Documents  install_ngx.sh      nfs.sh    Templates
    17 a.txt         Downloads  mon_nfs.sh          nginx.conf    test.txt
    18 checkmem.sh     d.txt        mon_nginx.sh      onkeyinstall    Videos
    19 
    20 >>>:ls /tmp
    21 {'data_size': 191}
    22 来自客户端消息systemd-private-e7b8cd4ded9b474c9a3d50fbae61134e-cups.service-FDqOvd
    23 systemd-private-e8a7a17af09640a085e380f1a076a6fb-cups.service-vc3Hrz
    24 VMwareTools-8.8.2-590212.tar.gz
    25 vmware-tools-distrib
    运行结果
  • 相关阅读:
    git 的安装与初始化
    django的ORM
    elasticsearch基本使用
    给django视图类添加装饰器
    python的编码
    为django项目配置celery的后台启动
    django+celery +rabbitmq
    hadoop安装
    django中间件
    Blockchain For Dummies(IBM Limited Edition
  • 原文地址:https://www.cnblogs.com/hongyongshang/p/6805012.html
Copyright © 2020-2023  润新知