gpt4 book ai didi

python - 我需要服务器向所有客户端发送消息(Python、套接字)

转载 作者:可可西里 更新时间:2023-11-01 02:31:55 25 4
gpt4 key购买 nike

这是我的服务器程序,它如何将从每个客户端接收到的数据发送到每个其他客户端?

import socket
import os
from threading import Thread
import thread

def listener(client, address):
print "Accepted connection from: ", address

while True:
data = client.recv(1024)
if not data:
break
else:
print repr(data)
client.send(data)

client.close()

host = socket.gethostname()
port = 10016

s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,port))
s.listen(3)
th = []

while True:
print "Server is listening for connections..."
client, address = s.accept()
th.append(Thread(target=listener, args = (client,address)).start())

s.close()

最佳答案

如果需要向所有客户端发送消息,则需要以某种方式保存所有客户端的集合。例如:

clients = set()
clients_lock = threading.Lock()

def listener(client, address):
print "Accepted connection from: ", address
with clients_lock:
clients.add(client)
try:
while True:
data = client.recv(1024)
if not data:
break
else:
print repr(data)
with clients_lock:
for c in clients:
c.sendall(data)
finally:
with clients_lock:
clients.remove(client)
client.close()

将其中的一部分分解为单独的函数可能会更清楚,例如执行所有发送的 broadcast 函数。

无论如何,这是最简单的方法,但是它有问题:

  • 如果一个客户端的连接速度很慢,其他人都可能无法向其写入数据。当他们轮到他们写时阻塞时,他们没有读取任何东西,所以你可能会溢出缓冲区并开始断开每个人的连接。
  • 如果一个客户端出现错误,其线程正在写入该客户端的客户端可能会得到异常,这意味着您最终将断开与错误用户的连接。

因此,更好的解决方案是为每个客户端提供一个队列,以及一个为该队列提供服务的写入线程以及读取线程。 (然后您可以通过各种方式扩展它——对队列进行限制,以便人们停止尝试与落后太远的人交谈,等等)


正如 Anzel 所指出的,除了为每个客户端使用一个(或两个)线程之外,还有一种不同的方式来设计服务器:使用一个 reactor 来复用所有客户端的事件。

Python 3.x 内置了一些很棒的库,但 2.7 只有笨重且过时的 asyncore/asynchat 和低级 select

正如Anzel所说,Python SocketServer: sending to multiple clients有一个使用asyncore的答案,值得一读。但我实际上不会使用它。如果您想在 Python 2.x 中编写基于 react 堆的服务器,我要么使用更好的第三方框架,如 Twisted ,要么找到或编写一个非常简单的直接位于 select 上的框架.

关于python - 我需要服务器向所有客户端发送消息(Python、套接字),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27139240/

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