2017-06-13 160 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() 
相關問題