【问题标题】:Python UDP recvfrom() specific addressPython UDP recvfrom() 具体地址
【发布时间】:2012-02-13 08:21:04
【问题描述】:

我在这段代码中看到的问题是,虽然它正在工作,但一些客户端(玩家)发送到该服务器的信息最终会以方法“permission”结束,而原本打算以“clientRequests”结束,因为两者其中有recvfrom()。所以,如果我可以将我想要的信息指定为 recvfrom() 的参数,它会解决它。我相信使用 C++ 是可能的,但是使用 python 是可能的,以及如何? 使用 TCP 不存在这个问题,但我更喜欢 UDP。

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

'permission' 用于处理新客户端的连接。

问题是位置、从客户端发送的事件等信息不会在“许可”下得到处理。

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

【问题讨论】:

    标签: python networking udp recv


    【解决方案1】:

    我相信线程不必要地使像这样的简单 UDP 服务器复杂化。只需监听套接字并根据是否已经看到数据包的源地址来分派调用。

    不,常规的recvfrom(2) 系统调用不允许您“过滤”从哪个地址获取数据,而只能获取该信息。过滤是在 UDP 套接字上使用 connect(2) 完成的,但这会将您限制为每个套接字只有一个源。

    【讨论】:

    • 嗯,这实际上是我和朋友一起做的一个在线游戏项目,每个客户都有一个线程很重要,并且那个线程只听那个地址:( PS我什么'已经出现了显然不是整个服务器类编辑:我要查找连接(2)谢谢..
    • 只是一个建议 - 尝试从状态机的角度来考虑游戏。您可能会发现您关于必须拥有线程的假设是错误的。
    猜你喜欢
    • 2015-05-23
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 2016-01-09
    • 2023-04-04
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多