Socket.sendall()不发送到所有连接的客户端

时间:2014-12-21 22:32:37

标签: python sockets tcp

我正在努力使用.sendall()方法进行客户端/服务器设置。多个客户端可以单独连接并向服务器发送消息并获得回显响应。但是,我希望发送的消息能够在类似聊天的环境中显示给所有连接的客户端。

这是在服务器应用程序上运行的代码。

def clientHandler(conn, addr):
    name = addr[0]
    print(addr, " connected to the server")
    while True:
        data = conn.recv(1024)
        if tostr(data)[0:5] == '/name':
            print('setting name')
            setname(data)
        if not data:
            break
        conn.sendall(str.encode(checkname(addr[0]) + tostr(data)))
        print('Received Message: ', tostr(data))


HOST = '' #LOCALHOST
PORT = 1400

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(999999)

print('Server is running' + '-'*10)

for i in range(999999):
    conn, addr = sock.accept()
    Thread(target = clientHandler, args = (conn, addr)).start()

sock.close()

提前谢谢

1 个答案:

答案 0 :(得分:1)

正如我最初在评论中所说(但现在决定在答案中说得更好),sendall将所有字​​节发送到单个连接。您需要添加以下内容:

lock = threading.Lock()
all_clients = []

在顶部;在主循环中,您现在只有conn, addr = sock.accept(),有

conn, addr = sock.accept()
with lock:
    all_clients.append(conn)

clientHandler,您现在只有conn.sendall(str.encode(checkname(addr[0]) + tostr(data))),而不是

with lock:
    for c in all_clients:
        c.sendall(str.encode(checkname(addr[0]) + tostr(data)))

IOW,你需要在服务器中显式编写“广播”业务逻辑 - 它绝对不是sendall中隐含的(你可能误解了它的语义)。