Python 3:套接字服务器使用sendto()函数发送到多个客户端 [英] Python 3: Socket server send to multiple clients with sendto() function

查看:249
本文介绍了Python 3:套接字服务器使用sendto()函数发送到多个客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a server set up with sockets and threading, and when I connect multiple clients to it, if a client sends a message, the server repeats that same message back to it, instead of to all other connected clients. For example:

#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.")

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

I have read the following sources, but to no avail:

将数据发送到多个客户端的python tcp服务器

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

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

What must I do to make it send user1's message to all other users through the server?

所有server.py代码:

Edit 1: All server.py code:

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()

推荐答案

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

I see a few issues in your code -

  1. 您正在启动clientHandler线程,但是随后您没有使主线程加入任何线程,这可能导致主线程在子线程完成处理之前死亡,我想您想保存Thread对象您创建一个变量,然后使它们加入主线程.

  1. You are starting clientHandler threads, but then you are not making the main thread join any , this may cause main thread to die before the child threads finish processing, I think you would want to save the Thread objects you create to a variable and then make them join the main thread.

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

Instead of making the clientHandlers directly, you should first wait for accepting a connection from client (outside the handler function) and once you get the connection, add it to list of clients and send it over to the clientHandler.

在您的代码中-for client in clients: c.sendto(data, client) m将数据发送到所有客户端,而不是应该通过检查addr来检查client不是该线程正在服务的client.线程正在维修.

In your code - for client in clients: c.sendto(data, client) m this sends data to all clients ,instead you should check if client is not the client that this thread is servicing, by checking against the addr that this thread is servicing.

示例更改-

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()

这篇关于Python 3:套接字服务器使用sendto()函数发送到多个客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆