TCP/Socket与subprocess
我们准备做一个可以在Client端远程执行Server端的shell命令并拿到其执行结果的程序,而涉及到网络通信就必然会使用到socket模块,此外还需要subprocess模块拿到命令执行结果。
关于传输层协议的选择我们采用TCP协议,因为它是可靠传输协议且一次传输的数据量要比UDP协议更大。
以下是Server端的代码实现:
import subprocess
from socket import *
# 默认直接实例化socket是IPV4 + TCP协议
server = socket()
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
server.bind(("localhost", 8888))
server.listen(5)
while 1:
conn, clientAddr = server.accept()
print("%s connect server" % clientAddr[0])
while 1:
try:
command = conn.recv(1024)
if not command:
break
result = subprocess.Popen(
args=command.decode("u8"),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# get success result
successOut = result.stdout.read()
# get error result
errorOut = result.stderr.read()
# type == bytes
dataBody = successOut or errorOut
conn.send(dataBody)
except ConnectionResetError as e:
break
print("%s close connect" % clientAddr[0])
conn.close()
以下是Client端代码的实现:
from socket import *
client = socket()
client.connect(("localhost", 8888))
while 1:
command = input(">>>").strip()
if not command:
continue
if command == "exit":
break
client.send(command.encode("u8"))
dataBody = client.recv(1024)
# windows server : decode("gbk")
# unix server : decode("u8")
print(dataBody.decode("u8"))
print("client close")
client.close()
使用测试,Client端输入命令:
>>>ls
__pycache__
socketClient.py
socketServer.py
>>>pwd
/Users/yunya/PythonProject
>>>cal
六月 2021
日 一 二 三 四 五 六
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
>>>
粘包现象
上面的测试看起来一切都非常完美,但如果Client端输入一条结果很长的命令时会出现一次性读取不完的Bug,如下所示:
>>>info vim
File: *manpages*, Node: vim, Up: (dir)
VIM(1) VIM(1)
NAME
vim - Vi IMproved, a programmer's text editor
SYNOPSIS
vim [options] [file ..]
vim [options] -
vim [options] -t tag
vim [options] -q [errorfile]
ex
view
gvim gview evim eview
rvim rview rgvim rgview
DESCRIPTION
Vim is a text editor that is upwards compatible to Vi. It can be used
to edit all kinds of plain text. It is especially useful for editing
programs.
There are a lot of enhancements above Vi: multi level undo, multi win-
dows and buffers, syntax highlighting, command line edi