python套接字多客户端发送,

2024-05-16 04:28:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我遇到了一个问题,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()

Tags: importclientsendformatserverdefsocketconn
2条回答

如果有人想只向一个客户端发送数据,请在此处输入代码 我认为它看起来很业余,但它很管用。 输入命令: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)

服务器代码为每个客户机创建一个线程,该线程从用户处获取输入并迭代所有客户机连接,而不仅仅是新的客户机连接。您可能想考虑在客户端上重复一个线程,并在主循环中添加客户端连接。

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

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)

相关问题 更多 >