У меня есть базовый сценарий клиент-сервер в Python с использованием сокетов. Сервер привязывается к определенному порту и ждет клиентского соединения. Когда клиент подключается, ему предоставляется приглашение raw_input, которое отправляет введенные команды подпрограмме на сервер и передает результат обратно клиенту. Иногда, когда я выполняю команды от клиента, вывод будет зависать и не показывать мне запрос raw_input до тех пор, пока я не нажму клавишу [enter]. Сначала я думал, что это может быть проблема буфера, но это происходит, когда я использую команды с небольшим выходом, как «ясный» или «LS» и т.д.Скрипт клиент-сервер Python зависает, пока я не нажимаю [enter]
код клиента:
import os, sys
import socket
from base64 import *
import time
try:
HOST = sys.argv[1]
PORT = int(sys.argv[2])
except IndexError:
print("You must specify a host IP address and port number!")
print("usage: ./handler_client.py 192.168.1.4 4444")
sys.exit()
socksize = 4096
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
server.connect((HOST, PORT))
print("[+] Connection established!")
print("[+] Type ':help' to view commands.")
except:
print("[!] Connection error!")
sys.exit(2)
while True:
data = server.recv(socksize)
cmd = raw_input(data)
server.sendall(str(cmd))
server.close()
Серверный код:
import os,sys
import socket
import time
from subprocess import Popen,PIPE,STDOUT,call
HOST = ''
PORT = 4444
socksize = 4096
activePID = []
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn.bind((HOST, PORT))
conn.listen(5)
print("Listening on TCP port %s" % PORT)
def reaper():
while activePID:
pid,stat = os.waitpid(0, os.WNOHANG)
if not pid: break
activePID.remove(pid)
def handler(connection):
time.sleep(3)
while True:
cmd = connection.recv(socksize)
proc = Popen(cmd,
shell=True,
stdout=PIPE,
stderr=PIPE,
stdin=PIPE,
)
stdout, stderr = proc.communicate()
if cmd == ":killme":
connection.close()
sys.exit(0)
elif proc:
connection.send(stdout)
connection.send("\nshell => ")
connection.close()
os._exit(0)
def accept():
while 1:
global connection
connection, address = conn.accept()
print "[!] New connection!"
connection.send("\nshell => ")
reaper()
childPid = os.fork() # forks the incoming connection and sends to conn handler
if childPid == 0:
handler(connection)
else:
activePID.append(childPid)
accept()
Вопрос в том, что мне здесь не хватает? Кажется, что клиент должен иметь возможность перейти от вывода на печать к командной строке скорее без видимых на вид. Есть предположения? – ohdae
Возможно, вы захотите проверить [argparse] (http://docs.python.org/library/argparse.html#module-argparse) аргументы командной строки - когда это так просто, как ваш код в настоящее время, на самом деле он не нужен , но если он становится более сложным, стоит посмотреть. –
Весь код на самом деле немного сложнее, чем на самом деле, это всего лишь фрагменты клиентского сервера.Я просто немного перетасовал его, поэтому мои примеры не были на 5 страниц. Спасибо за совет, хотя :) – ohdae