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
运行结果

 

转载于:https://www.cnblogs.com/hongyongshang/p/6805012.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值