2012-01-18 168 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