Python 'socketserver'只处理第一个请求



客户端输出

为了说明这个问题,下面是在客户端上运行时的代码。可以看出,第一个命令成功了(它总是成功的(,即使在返回stderr的错误命令的情况下,它也会成功。

Pwny ~>df
Filesystem     1K-blocks     Used Available Use% Mounted on
udev             1895788        0   1895788   0% /dev
tmpfs             386392     1416    384976   1% /run
/dev/sda1      478612200 43470808 410755756  10% /
tmpfs            1931948    78200   1853748   5% /dev/shm
tmpfs               5120        0      5120   0% /run/lock
tmpfs             386388       60    386328   1% /run/user/1000
Pwny ~>pwd
Pwny ~>pwd
[~] Connection aborted
Pwny ~>

服务器输出

这是我的服务器的输出。

└─$ /bin/python3 /home/user/Desktop/tcpserver/socketserver.py
[*] Started server 0.0.0.0:9999
[*] 192.168.137.1:1051 connected
[~] 192.168.137.1:1051 df

TCP客户端程序

这是我的客户代码:

import socket
class TCPClient:
@staticmethod
def run(host, port, buffer_size=1024, encoding='utf-8'):
HOST = host
PORT = port
BUFFER_SIZE = buffer_size
ENCODING = encoding
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
while True:
tx: bytes = bytes(input("Pwny ~>"), ENCODING)
tx += b"n"
if tx == b"exit":
break
else:
try:
s.sendall(tx)
full_msg: bytes = b''
while True:
msg: bytes = s.recv(BUFFER_SIZE)
if len(msg) == 0:
break
full_msg += msg
print(full_msg.decode(ENCODING))
except ConnectionAbortedError:
print("[~] Connection aborted")
except OSError:
print("[~] An OS error occurred")

if __name__ == '__main__':
tcp_client = TCPClient()
tcp_client.run(host='192.168.137.2', port=9999, buffer_size=128, encoding='utf-8')

TCP SocketServer程序

这是socketserver程序(我怀疑我在这里做了什么,非常感谢帮助(

import socketserver
import subprocess
from subprocess import CompletedProcess
class ThreadingServer(socketserver.ThreadingMixIn,socketserver.TCPServer): pass
class TCPRequestHandler(socketserver.StreamRequestHandler):
def setup(self) -> None:
return super().setup()
def handle(self) -> None:
ENCODING: str = 'utf-8'
BUFFER_SIZE: int = 128
client_address: str = self.request.getpeername()[0]
client_port: int = self.request.getpeername()[1]
print(f"[*] {client_address}:{client_port} connected")
client_cmd: str = self.rfile.readline().decode(ENCODING).strip()
print(f"[~] {client_address}:{client_port} {client_cmd}")
output: CompletedProcess = subprocess.run(client_cmd,shell=True,capture_output=True)
""" Returns 0 for success and >= 1 for failure"""
if output.returncode == 0: # success
self.wfile.write(output.stdout)
else: # failure when > 0
self.wfile.write(output.stderr)
def finish(self) -> None:
return super().finish()
if __name__ == '__main__':
with ThreadingServer(('0.0.0.0',9999),TCPRequestHandler) as server:
print(f"[*] Started server {server.server_address[0]}:{server.server_address[1]}")
server.serve_forever()

客户端和服务器都有问题。

客户端使用套接字.recv()读取数据,但当服务器输出完成时,这将在第一个命令结束时永远阻塞。它将仅在服务器关闭套接字时的EOF处返回b''。由于服务器问题(如下(,它似乎可以工作。

服务器代码只读取一行,生成命令,发送输出,然后从handle()返回,然后关闭连接。由于这个关闭,客户端实际上可以工作(它从recv()获得b''(。

要修复服务器,请循环执行readline(),直到它在发送命令输出后返回b''(客户端关闭的套接字(,最好是flush()写入流。

示例服务器处理程序:

def handle(self) -> None:
ENCODING: str = 'utf-8'
BUFFER_SIZE: int = 128
client_address: str = self.request.getpeername()[0]
client_port: int = self.request.getpeername()[1]
print(f"[*] {client_address}:{client_port} connected")
while True:
line: str = self.rfile.readline()
if line == b'':
break
client_cmd: str = line.decode(ENCODING).strip()
print(f"[~] {client_address}:{client_port} {client_cmd}")
output: CompletedProcess = subprocess.run(client_cmd,shell=True,capture_output=True)
""" Returns 0 for success and >= 1 for failure"""
if output.returncode == 0: # success
self.wfile.write(output.stdout)
else: # failure when > 0
self.wfile.write(output.stderr)
self.wfile.flush()

要修复客户端和整个设置,您可能需要实现某种框架,对于客户端命令,这目前是一条换行符(因为您使用了readline(,但对于服务器输出,您需要找到一个单独的框架。

相关内容

  • 没有找到相关文章

最新更新