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:\pdata\day36\job 的目录
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
运行结果

 

posted @ 2017-05-04 02:10  福临  阅读(1310)  评论(0编辑  收藏  举报