python 套接字多客户端发送,

python socket multiclients sending,

我遇到了问题python 套接字服务器只向最后添加的一个客户端发送数据。 我试过使用 sendto(data, addr) 但它并不总是有效。 服务器应该作为 windows 中的远程命令行工作。 服务器与一个客户端通信,它没有任何问题,但如果有更多,它就无法工作。 Python版本:3.9 也许有人可以帮助我? 我把代码放在这里:

服务器

import socket
import sys
import threading
HEADER = 64
PORT = 5050
SERVER = "192.168.0.117"
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
server.settimeout(2)
clients = []


def handle_client(conn, addr):
    print(f"[NEW CONNECTION] {addr} connected.")
    clients.append(addr)
    print(clients)
    connected = True
    while connected:
        command = input("[SERVER] => ")
        for client in clients:
            conn.sendto(command.encode(FORMAT), client)
            print(f"Sending data: {command} to {client}")
    conn.close()


def start():
    server.listen()
    print(f"[LISTENING] Server is listening on {SERVER}")
    while True:
        try:
            conn, addr = server.accept()
            thread = threading.Thread(target=handle_client, args=(conn, addr))
            thread.start()
        except socket.timeout:
            continue
        except socket.error as e:
            print(e)
            sys.exit(1)


if __name__ == '__main__':
    start()

这是客户:

import socket
import os
import sys
HEADER = 64
PORT = 5050
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
SERVER = "192.168.0.117"
ADDR = (SERVER, PORT)

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)


# it doesn't work yet
def send(msg):
    message = msg.encode(FORMAT)
    msg_length = len(message)
    send_length = str(msg_length).encode(FORMAT)
    send_length += b' ' * (HEADER - len(send_length))
    client.send(send_length)
    client.send(message)
    

def command_bot(command):
    if len(command) > 1:
        try:
            comm = ""
            for x in command:
                comm += x + " "
            os.system(comm)
            print(comm)
        except os.error as e:
            print(e)
            sys.exit(1)

    
def start():
    while True:
        command = str(client.recv(2048).decode(FORMAT)+" ")
        comm = []
        y = ""
        for x in command:
            if x != " ":
                y += x
            else:
                comm.append(y)
                y = ""
        if comm[-1] == "":
            comm = comm[:-1]
        command_bot(comm)

if __name__ == '__main__':
    start()

服务器代码正在为每个客户端创建一个线程,该线程从用户那里获取输入并遍历所有客户端连接,而不仅仅是新的客户端连接。您可能需要考虑让一个线程遍历客户端并在主循环中添加客户端连接。

试试这个适用于多个客户端连接的更新服务器代码:

def handle_client():
    while True:
        command = input("[SERVER] => ")
        for client in list(clients):
            conn = client[0]
            try:
                conn.sendall(command.encode(FORMAT))
                print(f"Sending data: {command} to {client[1]}")
            except Exception as ex:
                print ("ERROR:", ex)
                print("remove client:", client[1])
                clients.remove(client)
                try:
                    conn.close()
                except:
                    pass

def start():
    server.listen()
    print(f"[LISTENING] Server is listening on {SERVER}")
    threading.Thread(target=handle_client).start()
    while True:
        try:
            conn, addr = server.accept()
            print("client:", addr)
            clients.append((conn, addr))
        except socket.timeout:
            continue
        except socket.error as e:
            print(e)
            sys.exit(1)

你好,如果有人只想将数据发送给这里的​​一个客户端,请把代码放在这里 我认为它看起来很业余,但它确实有效。 输入命令:sendto -c <client's address ip> <command> 例子:sendto -c 192.168.0.117 start www.google.com

def handle_client():
    while True:
        command = input("[SERVER] => ")
        command = command.split()
        for client in list(clients):
            try:
                if len(command) > 1:
                    if len(command) > 3:
                        if client[1] == (command[2], client[1][1]) and command[0] == "sendto" and command[1] == "-c":
                            c = command[3:]
                            comm = ""
                            for x in c:
                                comm += x + " "
                            client[0].sendall(comm.encode(FORMAT))
                            print(f"Sending data: '{comm}' to {client[1]}")
                            continue
                if len(command) > 0 and command[0] != "sendto":
                    comm = ""
                    for x in command:
                        comm += x + " "
                    client[0].sendall(comm.encode(FORMAT))
                    print(f"Sending data: '{comm}' to {client[1]}")

            except Exception as ex:
                print("ERROR:", ex)
                print("remove client:", client[1])
                clients.remove(client)