2012-01-18 169 views
1

我用這段代碼看到的問題是,雖然它正在工作,但有些信息客戶端(播放器)發送到此服務器時,最終會在方法「權限」在'clientRequests',因爲他們都有recvfrom()。因此,如果我可以指定WHICH addr,我想從recvfrom()的參數中獲取信息,它可以解決這個問題。我相信這是可能的C++,但它是與python,以及如何? 有了TCP這個問題不存在,但我更喜歡UDP。Python UDP recvfrom()特定地址

類似於:recvfrom(512,address =(ip,port))?

「權限」用於處理連接的新客戶端。

問題在於,像「位置」這樣的信息,客戶發送的事件在「許可」時不會被照顧。

class Server: 
    def __init__(self): 
     #host = '192.168.0.2' 
     host = '127.0.0.1' 
     port = 50007 
     addr = (host, port) 
     self.UDPSock = socket(AF_INET, SOCK_DGRAM) 
     self.UDPSock.bind(addr) 
     self.UDPSock.settimeout(5.0) 
     self.searchForClients = True 
     self.playersOnline = [] 
     threading.Thread(target=self.permission).start() 
     Gui.add_event("Server online on port %s" % port) 


    def permission(self): 
     global _status 
     while self.searchForClients: 
      time.sleep(0.5) 
      _status.set("Status: Running; Connected: %s" % len(self.playersOnline)) 
      try: 
       clientMessage, addr = self.UDPSock.recvfrom(1024) # , MSG_PEEK 
      except: 
       clientMessage = "" 
      if clientMessage == "CONNECT" and addr not in self.playersOnline:      
       if self.searchForClients: 
        self.addNewClient(addr) 

      elif clientMessage == "DISCONNECT" and addr in self.playersOnline: 
       self.removeClient(addr) 

     Gui.add_event("No longer accepting logins") 
     return False 

    def clientRequests(self, addr): 
     latestRequest = time.time() 
     while addr in self.playersOnline: 
      time.sleep(0.01) 
      try: 
       data, requestAddr = self.UDPSock.recvfrom(1024) 
      except: 
       requestAddr, data = "", "" 
      if requestAddr == addr: 
       latestRequest = time.time() 
       dataCommand = data.split(':') 
      if time.time() - latestRequest > 2: 
       if addr in self.playersOnline: 
        self.removeClient(addr) 

     if not self.searchForClients:  
      Gui.add_event("Player %s(%s) forcibly removed" % addr) 
     return False 

回答

1

我相信線程不必要地使這個簡單的UDP服務器複雜化。只需監聽套接字並根據數據包的源地址是否已被查看來發送呼叫。

而不是,通常recvfrom(2)系統調用不允許您「過濾」您從中獲取數據的地址,只能獲取該信息。在UDP套接字上使用connect(2)進行過濾,但是這將每個套接字限制爲單個源。

+0

嗯,這實際上是一個在線遊戲項目,我與朋友在一起,重要的是爲每個客戶端設置一個線程,並且只有一個線程只能聽取該地址:(PS我在那裏顯示的內容顯然不是整個服務器類編輯:我要查找連接(2)謝謝.. – KnasScripter 2012-01-18 16:38:34

+0

只是一個建議 - 嘗試從狀態機的角度思考遊戲。你可能會發現,你的假設必須有線程是錯誤的。 – 2012-01-18 16:48:18