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端
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()
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