【发布时间】:2013-11-29 16:27:42
【问题描述】:
我正在尝试使用套接字在 pygame 中创建一个两人游戏,问题是,当我尝试在此行上接收数据时:
message = self.conn.recv(1024)
python 挂起,直到它得到一些数据。这样做的问题是当客户端没有通过套接字发送任何内容并导致黑屏时暂停游戏循环。我怎样才能阻止 recv 这样做?
提前致谢
【问题讨论】:
-
使用多线程或异步io
我正在尝试使用套接字在 pygame 中创建一个两人游戏,问题是,当我尝试在此行上接收数据时:
message = self.conn.recv(1024)
python 挂起,直到它得到一些数据。这样做的问题是当客户端没有通过套接字发送任何内容并导致黑屏时暂停游戏循环。我怎样才能阻止 recv 这样做?
提前致谢
【问题讨论】:
使用非阻塞模式。 (见socket.setblocking。)
或者在调用recv之前检查是否有可用数据。
例如,使用select.select:
r, _, _ = select.select([self.conn], [], [])
if r:
# ready to receive
message = self.conn.recv(1024)
【讨论】:
您可以使用信号模块来停止挂起的 recv 线程。
在recv线程中:
try:
data = sock.recv(1024)
except KeyboardInterrupt:
pass
在解释线程中:
signal.pthread_kill(your_recving_thread.ident, signal.SIGINT)
【讨论】:
我知道这是一篇旧帖子,但由于我最近在从事类似的项目,所以我想添加一些尚未针对遇到相同问题的人说明的内容。
您可以使用线程创建一个新线程,该线程将接收数据。之后,在主线程中正常运行游戏循环,并在每次迭代中检查接收到的数据。接收到的数据应由数据接收线程放入队列中,并由主线程从该队列中读取。
#other imports
import queue
import threading
class MainGame:
def __init__(self):
#any code here
self.data_queue = queue.Queue()
data_receiver = threading.Thread(target=self.data_receiver)
data_receiver.start()
self.gameLoop()
def gameLoop(self):
while True:
try:
data = self.data_queue.get_nowait()
except queue.Empty:
pass
self.gameIteration(data)
def data_receiver(self):
#Assuming self.sock exists
data = self.sock.recv(1024).decode("utf-8")
#edit the data in any way necessary here
self.data_queue.put(data)
def gameIteration(self, data):
#Assume this method handles updating, drawing, etc
pass
请注意,此代码在 Python 3 中。
【讨论】: