Python 3:套接字服务器使用sendto()函数发送到多个客户端

时间:2015-06-27 07:41:35

标签: python multithreading sockets python-3.x

我有一个带有套接字和线程的服务器,当我连接多个客户端时,如果客户端发送消息,服务器会将相同的消息重复给它,而不是所有其他连接的客户端。例如:

#server terminal
Server is connected on 8000
('127.0.0.1', 50328) is Connected
('127.0.0.1', 50329) is Connected
Received Message b'hi\n'

#Client 1 terminal
#input
[user1]hi
#returns:
[user1] b'hi\nhi\n'[user1]

#Client 2 terminal
#doesn't return anything, just sits at the prompt
[user2]

服务器的相关代码是:

def clientHandler():
    c, addr = s.accept() 
    print(addr, "is Connected")
    if addr not in clients:
        clients.append(addr)
    try:
        while True:
            data = c.recv(1024)
            if not data: 
                break 
            print("Received Message ", repr(data))
            for client in clients:
                c.sendto(data, client)
    except:
        print("Error. Data not sent.")

我已阅读以下资料,但无济于事:

python tcp server sending data to multiple clients

https://docs.python.org/3/library/socket.html

我必须做些什么才能让用户通过服务器向所有其他用户发送消息?

编辑1: 所有server.py代码:

from socket import *
from threading import Thread

clients = []

def clientHandler():
    c, addr = s.accept() 
    print(addr, "is Connected")
    if addr not in clients:
        clients.append(addr)
    try:
        while True:
            data = c.recv(1024)
            if not data: 
                break 
            for client in clients:
                c.sendto(data, client)
    except:
        print("Error. Data not sent to all clients.")

HOST = '' #localhost
PORT = 8000

s = socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(5)

print("Server is running on "+ str(PORT))

#Thread(target=clientHandler).start()
#Thread(target=clientHandler).start()
#Thread(target=clientHandler).start()

for i in range(5): 
    Thread(target=clientHandler).start()

s.close()

1 个答案:

答案 0 :(得分:0)

我在您的代码中看到了一些问题 -

  1. 你正在启动clientHandler线程,但是你没有让主线程连接任何,这可能导致主线程在子线程完成处理之前死掉,我想你想要保存{{1}您创建的变量对象,然后使它们加入主线程。

  2. 您应该首先等待接受来自客户端的连接(在处理函数之外),然后在获得连接后,将其添加到客户端列表并将其发送到clientHandler,而不是直接创建clientHandler。

  3. 在您的代码中 - Thread m这会将数据发送给所有客户端,而应检查for client in clients: c.sendto(data, client)是否不是此线程正在服务的client,方法是检查该线程正在服务的client

  4. 示例更改 -

    addr