gpt4 book ai didi

python - Twisted 中的多重响应

转载 作者:行者123 更新时间:2023-11-28 22:57:30 25 4
gpt4 key购买 nike

我正在尝试使用 Twisted 和 Pygame 开发简单的 TCP、clinet/server 游戏,但我在向客户端发送数据时遇到了困难。 Twisted 不允许我连续发送多个回复。这就是我想要做的:

我有处理玩家状态变化并将它们重新发送给其他客户端的方法:

def handle_stateChanged(self, data):
#get playerState from client and override local copy of player
#check if all players are ready
#if needed, change gameState form 'inLOBBY' to 'inGAME'
#if gameState == 'inGAME', start 'proceed' method (see below)
#send message about player and game state to others

proceed 方法(使用 LoopingCall 每 1s/30 调用一次)简单地计算所有游戏内容并将其发送给玩家。这两个函数相互阻塞,单独工作时它们工作得很好,但是当一起工作时,只有来自其中一个的数据到达目的地。同样这样的事情不起作用:

def dataRecived(self, data):
...
sendData(data1) #only data1 is delivered
sendData(data2)
...

我不知道这是 TCP 的工作方式还是我对 Twisted 缺乏了解。我应该如何向客户端发送更新并在后台处理用户输入?

编辑:

class Server(Protocol):
def __init__(self, factory):
self.factory = factory
self.player = None #when connection is made here goes my player class
self.world = factory.world
...
self.factory.loop = LoopingCall(self.proceed)

def dataReceived(self, data):
data = pickle.loads(data)
#this calls 'handle_stateChanged'
getattr(self, 'handle_{}'.format(data['header']))(data) #data[header] = 'stateChanged'

def handle_stateChanged(self, data):
isReady = data['isReady']
self.player.isReady = isReady

if isReady:
count = 0
for connection in self.factory.connections.values():
if connection.player.isReady:
count += 1

if count == len(self.factory.connections) and count > 1 and self.world.state == 'inLOBBY':
self.world.state = 'inGAME'
self.world.playersDistribution(self.factory.connections)
self.factory.loop.start(1 / 30)

data['state'] = self.world.state
data['players'] = self.getPlayers()
self.sendToOthers(data)

def sendToOthers(self, data, omitId = None):
connections = self.factory.connections

for key in connections.keys():
if key != omitId:
connections[key].sendData(data)

def proceed(self):
#It's only a prototype of my method.
#The point is that the client keep getting
#'test' and data from self.sendToOthers(data) in handle_stateChanged
#is not being delivered even if the method (handle_stateChanged) is called

if self.world.state != 'inGAME':
return

data = {'header' : 'message', 'body' : 'test'}
#When i comment this out, handle_stateChanged works fine and sends data
self.sendToOthers(data)

class ServerFactory(Factory):

def __init__(self, world):
self.world = world
self.connections = {}

def buildProtocol(self, addr):
return Server(self)

最佳答案

您的服务器存在远程任意代码执行漏洞。

在极少数情况下(如果有的话)您应该对从网络接收的数据进行 unpickle。这样做允许任何对等点出于任意的、可能是恶意的目的劫持您的服务器。 Note the big red box in the pickle documentation .

除了这个严重的安全问题之外,您遇到的只有第一个被发送的数据被解释的问题可能是由于两个数据在穿过网络时被连接在一起造成的。您的接收代码没有适当的框架支持,因此无法判断有两条消息。碰巧 pickle 将从第一条消息加载数据并忽略代表第二条消息的额外数据,有效地将数据丢弃在地板上。

如果切换到更具表现力的协议(protocol)(比传输未成帧的 pickle 字符串的裸 TCP 更具表现力),例如 AMP,那么安全问题和成帧问题都可以得到解决。 .

关于python - Twisted 中的多重响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14588131/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com