2017-06-13 169 views
0

我正在Python中开发一个服务器监控实用程序,我想处理从macOS到Haiku的所有事情。它被分成一个连接到并查询多个服务器的客户端。现在我正在使用在Parallels虚拟机上运行Debian的服务器在macOS主机上测试客户端。然而,我没有承诺我做出的确实工作到GitHub的新变化,然后做了一些改变,打破了整个事情。我只会包含我的代码的相关部分。“AttributeError”我在这里做错了什么?

这是来自客户端。

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加密套接字,但如果它甚至不能以纯文本工作,我就无法做到这一点。

+3

堆栈跟踪_immensely_比仅仅错误消息更有用。 Stacktraces是有原因发明的。请张贴你的,这样就可以看到错误发生在哪里。 – 9000

+0

看起来'incomingCommand'是'None',你是否在早些时候定义它? – cssko

+2

我怀疑你正在使用'exec'并试图'解码'的结果。但是'exec' *总是*返回'None'。因此你的错误。对于你正在做的任何事情,可能比使用exec更好。几乎可以确定。 –

回答

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() 
相关问题