繁体   English   中英

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

[英]Python 3: Socket server send to multiple clients with sendto() function

我有一台设置有套接字和线程的服务器,当我将多个客户端连接到该服务器时,如果一个客户端发送一条消息,则服务器会向该服务器重复发送同一条消息,而不是发送给所有其他已连接的客户端。 例如:

#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服务器将数据发送到多个客户端

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

我该怎么做才能使其通过服务器将user1的消息发送给所有其他用户?

编辑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. 您正在启动clientHandler线程,但随后没有使主线程加入任何线程,这可能导致主线程在子线程完成处理之前死亡,我想您想将创建的Thread对象保存到变量中,然后他们加入主线程。

  2. 而不是直接建立clientHandlers,您应该首先等待从客户端(在处理程序功能之外)接受连接,一旦获得连接,将其添加到客户端列表中并将其发送到clientHandler。

  3. 在你的代码- for client in clients: c.sendto(data, client) m该将数据发送到所有客户端,而不是你应该检查一下client是不是client ,这个线程是服务,通过对检查addr ,这个线程是服务。

示例更改-

from socket import *
from threading import Thread

clients = []

def clientHandler(c, addr):
    global clients
    print(addr, "is Connected")
    try:
        while True:
            data = c.recv(1024)
            if not data: 
                break 
            for client in clients:
                if addr != client:
                    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()
trds = []

for i in range(5): 
    c, addr = s.accept() 
    clients.append(addr)
    t = Thread(target=clientHandler, args = (c, addr))
    trds.append(t)
    t.start()

for t in trds:
    t.join()

s.close()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM