我正在使用Python开发一个服务器监控实用程序,我想处理从macOS到Haiku的所有内容。它分为连接和查询多个服务器的客户端。现在,我正在测试macOS主机上的客户端,并在Parallels VM中运行Debian上的服务器。但是,我没有提交我做的做对GitHub工作的新更改,然后做了一些改变,打破了整个事情。我只会包含与我相关的代码部分。
这是来自客户。
def getServerInfoByName(serverName):
serverIndex = serverNames.index(serverName)
serverAddress = serverAddressList[serverIndex]
serverPort = serverPorts[serverIndex]
serverUsername = serverUsernames[serverIndex]
return serverAddress, serverPort, serverUsername
for server in serverNames:
try:
if server != None:
serverInfo = getServerInfoByName(server)
exec(server + "Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)")
exec(server + "Socket.connect(('" + serverInfo[0] + "', " + serverInfo[1] + "))")
except ConnectionRefusedError:
print("Could not establish a connection to " + server + ".")
print(divider)
sys.exit()
def clientLoop():
sys.stdout.write(termcolors.BLUE + "-> " + termcolors.ENDC)
commandInput = input()
splitCommand = commandInput.split(' ')
whichServer = splitCommand[0]
if splitCommand[0] == "exit":
sys.exit()
# Insert new one word client commands here
elif len(splitCommand) < 2:
print("Not enough arguments")
print(divider)
clientLoop()
elif splitCommand[1] == "ssh":
serverInfo = getServerInfoByName(whichServer)
os.system("ssh " + serverInfo[2] + "@" + serverInfo[0])
print(divider)
clientLoop()
# Insert new external commands above here (if any, perhaps FTP in the
# future).
# NOTE: Must be recursive or else we'll crash with an IndexError
# TODO: Possibly just catch the exception and use that to restart the
# function
else:
whichServer = splitCommand[0]
commandToServer = splitCommand[1]
exec(whichServer + "Socket.send(commandToServer.encode('utf-8'))")
response = exec(whichServer + "Socket.recv(1024)")
print(response.decode('utf-8'))
print(divider)
clientLoop()
clientLoop()
这是来自服务器。
### Start the server
try:
incomingSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
incomingSocket.bind((address, port))
except OSError:
print("The configured address is already in use.")
print("The problem should solve itself in a few seconds.")
print("Otherwise, make sure no other services are using")
print("the configured address.")
sys.exit()
incomingSocket.listen(1)
### Main loop for the server
while True:
clientSocket, clientAddress = incomingSocket.accept()
incomingCommand = clientSocket.recv(1024)
command = incomingCommand.decode('utf-8')
if command != None:
if command == "os":
clientSocket.send(osinfo[0].encode('utf-8'))
elif command == "hostname":
clientSocket.send(osinfo[1].encode('utf-8'))
elif command == "kernel":
clientSocket.send(osinfo[2].encode('utf-8'))
elif command == "arch":
clientSocket.send(osinfo[3].encode('utf-8'))
elif command == "cpu":
cpuOverall = getOverall()
cpuOverallMessage = "Overall CPU usage: " + str(cpuOverall) + "%"
clientSocket.send(cpuOverallMessage.encode('utf-8'))
elif command == "stopserver":
incomingSocket.close()
clientSocket.close()
sys.exit()
else:
clientSocket.send("Invalid command".encode('utf-8'))
每当我尝试向服务器发送命令时,客户端会在尝试解码来自服务器的响应时立即与AttributeError: 'NoneType' object has no attribute 'decode'
崩溃。最终我想用AES加密套接字,但如果它甚至不能以纯文本形式工作,我就无法做到。
答案 0 :(得分:0)
exec
不会返回任何内容。您不应使用exec
生成变量名,而是使用字典来存储套接字。
servers = {}
for name, address, port, username in zip(serverNames, serverAddressList, serverPorts, serverUsernames):
try:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.connect((address, port))
servers[name] = server, address, port, username
except ConnectionRefusedError:
print("Could not establish a connection to {}.".format(name))
print(divider)
sys.exit()
def client_loop():
while True:
sys.stdout.write("{}-> {}".format(termcolors.BLUE,termcolors.ENDC))
command = input().split()
which_server = command[0]
if which_server == "exit":
break
elif len(command) < 2:
print("Not enough arguments")
print(divider)
elif command[1] == "ssh":
_, address, _, username = servers[which_server]
os.system("ssh {}@{}".format(username, address))
print(divider)
else:
server = servers[which_server][0]
server.sendall(command[1].encode('utf-8'))
response = server.recv(1024)
print(response.decode('utf-8'))
print(divider)
client_loop()