我遇到一個問題,Python socket服務器只向最后加入的一個客戶端發送資料。
我試著用sendto(data, addr),但它并不總是有效。
這個服務器應該像windows中的遠程命令列一樣作業。
服務器與一個客戶端通信,它沒有任何問題,但與更多的客戶端通信,它就是不作業。Python版本:3.9
也許有人能幫助我?
我把代碼放在這里:
SERVER
import socket
import sys
import threading
HEADER = 64
埠=5050
SERVER = "192.168.0.117"/span>
addr = (server, port)
FORMAT = 'utf-8'/span>
DISCONNECT_MESSAGE = "!DISCONNECT"。
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
server.settimeout(2)
客戶 = []
def handle_client(conn, addr)。
print(f" [NEW CONNECTION] {addr} connected.")
client.append(addr)
print(client)
connected = True(連接)。
while connected:
command = input(" [SERVER] => ")
for client in clients:
conn.sendto(command.encode(FORMAT), client)
print(f "發送資料。{command}到{client}")
conn.close()
def start()。
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}"/span>)
while True。
try:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
except socket.timeout。
繼續。
except socket.error as e:
print(e)
sys.exit(1)
if __name__ == '__main__':
start()
而這里是客戶端:
import socket
import os
import sys
HEADER = 64
埠=5050
格式='utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"。
SERVER = "192.168.0.117"/span>
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 = "": comm.append(y)
if comm[-1] == ":
comm = comm[:-1]
command_bot(comm)
if __name__ == '__main__'/span>:
start()
uj5u.com熱心網友回復:
同樣,如果有人想只向一個客戶端發送資料,這里有一段代碼。
我認為它看起來很業余,但它可以作業。
輸入命令。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(client):
try:
if len(command) > 1:
if len(command) > 3:
if client[1] == (command[2], client[1][1] ) and command[0] == "sendto"/span> and command[1] == "-c":
c = command[3:] 。
comm = "": c = command[3: ]
for x in c。
comm = x " "
client[0].sendall(comm.encode(FORMAT))
print(f "發送資料。'{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 "發送資料。'{comm}' to {client[1}")
except Exception as ex:
print("ERROR:"/span>, ex)
print("remove client:", client[1] )
clients.remove(client)
uj5u.com熱心網友回復:
服務器代碼正在為每個客戶端創建一個執行緒,該執行緒正在從用戶那里獲得輸入,并迭代所有的客戶端連接,而不僅僅是新的客戶端連接。您可能希望考慮讓一個執行緒遍歷客戶,并在主回圈中添加客戶連接。
嘗試一下這段更新的服務器代碼,它可以與多個客戶端連接一起使用:
def handle_client()。
while True:
command = input(" [SERVER] => ")
for client in list(client)。
conn = client[0]
try。
conn.sendall(command.encode(FORMAT))
print(f "發送資料。{command} to {client[1]}")
except Exception as ex:
print ("ERROR:"/span>, ex)
print("remove client:", client[1] )
client.remove(client)
try:
conn.close()
except:
pass: conn.close()
def start()。
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}"/span>)
threading.Thread(target=handle_client).start()
while True:
try:
conn, addr = server.accept()
print("client:"/span>, addr)
client.append((conn, addr))
except socket.timeout:
繼續。
except socket.error as e:
print(e)
sys.exit(1)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/308323.html
標籤:
