|
### 服务端配置
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from socket import *
import subprocess
import struct
ip_port=('127.0.0.1',9002)
ip_listen=5
buff_size=1024
# TCP 流式协议
tcp_server=socket(AF_INET,SOCK_STREAM)
# 绑定并监听端口
tcp_server.bind(ip_port)
# 允许back_log 允许有多少个队列
tcp_server.listen(ip_listen)
while True:
# 客户端连接信息,当客户端断开之后,服务端应允许其它客户端连接
conn,addr=tcp_server.accept()
print('客户端连接信息: %s' %conn)
while True:
try:
# 如果是空的,或者客户端非法退出,那么就直接退出程序
data=conn.recv(buff_size)
if not data:break
except Exception:
break
# subprocess接收到的命令应该是str格式,客户端发送过来的值是bytes格式,
res=subprocess.Popen(data.decode('utf-8'),shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
err=res.stderr.read()
# 如果这个值里有东西,说明它报错了直接返回它
if err:
cmd_res=err
else:
cmd_res=res.stdout.read()
# 如果为空比如cd .. 那么应该给它返回一个空值
if not cmd_res:
cmd_res='value is null '.encode('utf-8')
# 取出这个值最大的长度,并传递给客户端
length=len(cmd_res)
# --------------- 方法一 ---------------
# # length=str(length).encode('utf-8')
# conn.send(length)
# 将最大值给客户端,返回一个值过来,避免黏包
# retu_data=conn.recv(buff_size)
# if retu_data == b'ok':
# conn.send(cmd_res)
# --------------- 方法二 ---------------
# 黏包发送,第一次发送的值,固定为4字节,客户端接收的时候先接收4字节,再取数据
length_data=struct.pack('i',length)
conn.send(length_data)
conn.send(cmd_res)
conn.close()
tcp_server.close() |
|
|