2016-07-31 58 views
-1

我遇到了套接字/ tkinter登錄應用程序的問題。服務器在Raspberry Pi上,但即使服務器沒有啓動,我也沒有理由認爲這應該在啓動時掛起。我已經導入了一個我將要包含的模塊。使用套接字的Tkinter應用程序開始掛起

爲什麼它掛起?

這裏是我的客戶端代碼 - 那掛着一個: -

import socket, pickle 
import Tkinter as tk 
import loginutility 

class Server(object): 
    def __init__(self): 
     self.s = socket.socket() 
     self.p = 10000 
     self.ip = "192.168.1.120" 
    def addUser(self, userinfo): 
     puserinfo = pickle.dumps(userinfo) 
     self.s.connect((self.ip, self.p)) 
     self.s.sendall("check") 
     self.sendall(puserinfo) 
     if self.s.recv(1024) == False: 
      self.s.sendall("add") 
      self.send(puserinfo) 
      return True 
     else: 
      return False 
    def userDump(self): 
     self.s.sendall("userdump") 
     return pickle.loads(self.s.recv(1024)) 
class Main(tk.Tk): 
    def __init__(self): 
     tk.Tk.__init__(self) 

class LoginFrame(tk.Frame): 
    def __init__(self, parent): 
     tk.Frame.__init__(self, parent) 
     self.pack() 
     self.l = loginutility.LoginBox(self) 
     login = tk.Button(self, text="Login", command=self.login) 
     login.pack() 
    def login(self): 
     u, p = self.l.values() 
     users = Server.userDump() 
     if u in users and users[u] == p: 
      tk.Label(self, text="Success").pack() 

main = Main() 
mf = LoginFrame(main) 
main.mainloop() 

服務器代碼進行測試時是不是:

import loginutility as lu 
import socket 
import pickle 
s = socket.socket() 
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
address = '' 
port = 10000 
s.bind((address, port)) 
s.listen(5) 

users = lu.UserList("accounts") 
while True: 
     c, clientaddress = s.accept() 
     c.send("You're Connected") 
     d = c.recv(1024) 
     if d == "add": 
       userdata = c.recv(1024) 
       username, password = pickle.loads(userdata) 
       users.adduser(username, password) 
       print "User {} added with password of {}.".format(username, password) 
       c.send("Success") 
     elif d == "check": 
       username, password = pickle.loads(c.recv(1024)) 
       if users.checkuser(username) == False: 
         c.sendall(False) 
       else: 
         c.sendall(True) 
     elif d == "userdump": 
       c.send(pickle.dumps(users.dumpuser()) 

     c.close() 

必要loginutility代碼:

class LoginBox: 
    def __init__(self, parent): 
     self.l1=Label(parent, text="Username:").grid() 
     self.ubox=Entry(parent) 
     self.ubox.grid() 
     self.l2=Label(parent, text="Password:").grid() 
     self.pbox=Entry(parent, show="*") 
     self.pbox.grid() 
    def values(self): 
     return (self.ubox.get(), self.pbox.get()) 

class UserList: 
    def __init__(self, file=None): 
     self.users = {} 
     self.file = file 
     if file != None: 
      with open(file, "rb") as f: 
       self.users = pickle.load(f) 
    def adduser(self, user, pswrd): 
     self.users[user] = pswrd 
     if file != None: 
      with open(self.file, "wb") as f: 
       pickle.dump(self.users, f) 
    def dumpuser(self): 
     return self.users 

任何幫助非常感謝!

+0

如果服務器代碼在測試此代碼時未啓用,爲什麼要包含它?您應該將此代碼降低到仍能再現問題的絕對最少線條。在這種情況下,你可能會刪除2/3的代碼。 –

+0

您的服務器在測試時運行。當你調用self.s.connect()時,你的應用程序可能會永遠等待你的服務器響應。如果您的服務器沒有運行,客戶端將凍結在那裏。你可以通過添加一個[timeout](https://docs.python.org/2/library/socket.html#socket.socket.settimeout)到你的套接字來解決這個問題,你也可以通過做網絡東西來避免鎖定你的應用程序在另一個線程中。但要小心,因爲線程會讓你的應用程序**調試更復雜。 –

+0

@TomásGonzalezDowling不,不是的,我已經接受⬇️下面的答案,但謝謝你的建議! –

回答

0

它掛起的原因是因爲您將packgrid都混合在同一個父窗口小部件中。請看下面的代碼:

class LoginFrame(tk.Frame): 
    def __init__(self, parent): 
     tk.Frame.__init__(self, parent) 
     self.pack() 
     self.l = loginutility.LoginBox(self) 
     login = tk.Button(self, text="Login", command=self.login) 
     login.pack() 

在上面的代碼,你創建一個框架(self),創建一個LoginBox即是self一個孩子,一個按鈕,也是self孩子。該按鈕使用pack,而LoginBox.__init__使用grid

對於共享共同父項的小部件,您不能同時使用packgrid。在這種情況下,共同父項是LoginFrame的實例。