2017-06-13 9 views
0

Ich entwickle ein Dienstprogramm zur Serverüberwachung in Python, mit dem ich von Mac OS bis Haiku arbeiten möchte. Es ist in einen Client aufgeteilt, der mehrere Server verbindet und mehrere Server abfragt. Momentan teste ich den Client auf einem macOS-Host, wobei der Server auf Debian in einer Parallels-VM läuft. Allerdings habe ich die neuen Änderungen, die ich gemacht habe, tat arbeiten nicht zu GitHub, und machte dann einige Änderungen, die die ganze Sache brach. Ich werde nur die Teile meines Codes einbeziehen, die relevant sind."AttributeError" Was mache ich hier falsch?

Dies ist vom Client.

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() 

Und das ist vom Server.

### 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')) 

Jedes Mal, wenn ich versuche, einen Befehl an den Server zu senden, stürzt der Client mit AttributeError: 'NoneType' object has no attribute 'decode' sobald es der Antwort vom Server zu entschlüsseln versucht. Irgendwann möchte ich die Sockets mit AES verschlüsseln, aber das kann ich nicht, wenn es nicht einmal im Klartext funktioniert.

+3

Ein Stacktrace ist _immense_ nützlicher als nur eine Fehlermeldung. Stacktraces wurden aus einem bestimmten Grund erfunden. Bitte poste deine, damit es möglich ist zu sehen, wo der Fehler passiert. – 9000

+0

Sieht so aus als wäre "incomingCommand" 'None', definierst du es früher? – cssko

+2

Ich vermute, Sie verwenden 'exec' und versuchen, das Ergebnis davon zu" dekodieren ". Aber 'exec' * always * gibt' None' zurück. Daher dein Fehler. Es gibt wahrscheinlich einen besseren Weg, als 'exec' für alles zu verwenden, was Sie tun. Fast sicher. –

Antwort

0

exec gibt nichts zurück. Sie sollten keine Variablennamen mit exec generieren, sondern Wörterbücher verwenden, um die Sockets zu speichern.

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()