我在这段代码中看到的问题是,尽管它正在运行,但是一些信息客户端(播放器)发送到此服务器时最终会以“clientRequests”结束方法“权限”,因为两者都是他们有recvfrom()。所以,如果我可以指定WHICH addr我希望信息作为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
答案 0 :(得分:1)
我认为线程不必要地使像这样的简单UDP服务器复杂化。只需监听套接字并根据是否已经看到数据包的源地址来调度呼叫。
不,常规recvfrom(2)
系统调用不允许您“过滤”从中获取数据的地址,只是为了获取该信息。在UDP套接字上使用connect(2)
进行过滤,但这限制了每个套接字的单个源。