【发布时间】:2012-04-14 18:17:05
【问题描述】:
我在 Python 中有一个使用套接字的基本客户端-服务器脚本。服务器绑定到特定端口并等待客户端连接。当客户端连接时,它们会看到一个 raw_input 提示,该提示将输入的命令发送到服务器上的子进程,并将输出通过管道传回客户端。 有时,当我从客户端执行命令时,输出会挂起,并且在我按下 [enter] 键之前不会向我显示 raw_input 提示。 起初我以为这可能是缓冲区问题,但当我使用输出较小的命令时会发生这种情况,例如“clear”或“ls”等。
客户端代码:
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()
【问题讨论】:
-
问题是我在这里缺少什么?似乎客户端应该能够从打印输出转换到 shell 提示,而不是无缝。有什么想法吗?
-
您可能想查看argparse 以获取命令行参数 - 当它与您的代码一样简单时,它并不是真正需要的,但如果它变得更复杂,则值得一看。
-
整个代码实际上比这复杂得多,这只是一个客户端服务器sn-ps。我只是稍微改了一下,所以我的例子不是 5 页长。不过谢谢你的建议:)
标签: python sockets network-programming client