我有一个代码,需要执行从特定客户端发送和接收消息的任务。当我在服务器的发送函数中提到客户端地址时,会给我一个关键错误。
[NEW CONNECTION] ('10.14.0.1', 52870) connected.[ACTIVE CONNECTIONS] 1
Exception in thread Thread-3:
Traceback (most recent call last):
File "C:\Users\sho\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1009, in _bootstrap_inner
self.run()
File "c:\Users\sho\Documents\TcpCommExample\Server and clients\server 5.py", line 33, in run
clients["10.14.0.1"].send("VITA".encode(FORMAT))
KeyError: '10.14.0.1'我通过打印字典查过字典,其中确实存在客户地址,我不知道我在哪里出错。这是代码和任何帮助将不胜感激。
import socket, threading
import time
HEADER = 80
PORT = 9000
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
VITA_POSITIVE = "0000"
my_timer = 0
class ClientThread(threading.Thread):
def __init__(self, conn: socket.socket, addr: str):
threading.Thread.__init__(self)
self.conn = conn
self.addr = addr
def send(self, msg: str):
self.conn.sendall(msg.encode())
def run(self):
print(f"[NEW CONNECTION] {self.addr} connected.")
connected = True
while connected:
clients["10.14.0.1"].send("VITA".encode(FORMAT))
vita_response_iconet = clients["10.14.0.1"].recv(HEADER).decode(FORMAT)
print(vita_response_iconet)
if vita_response_iconet == VITA_POSITIVE:
print("VITA received from Iconet")
vita_iconet = 1
else:
print("VITA not received from Iconet")
vita_iconet = 0
clients["10.14.0.1"].send("VITA".encode(FORMAT))
vita_response_robot = clients["10.14.0.1"].recv(HEADER).decode(FORMAT)
print(vita_response_robot)
if vita_response_iconet == VITA_POSITIVE:
print("VITA received from Robot")
vita_robot = 1
else:
print("VITA not received from Robot")
vita_robot = 0
if vita_iconet and vita_robot == 1:
my_timer = 0
else:
my_timer = my_timer
self.conn.close()
def countup():
global my_timer
for x in range(1, my_timer+1):
time.sleep(1)
countup_thread = threading.Thread(target=countup)
countup_thread.start()
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
print('interesting')
print(conn)
print(addr)
thread = ClientThread(conn, addr)
print ('be ready')
thread.start()
clients[addr] = thread
print(f"[ACTIVE CONNECTIONS] {threading.active_count() - 2}")
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
clients = {}
connections = threading.Thread(target=start)
connections.start()
print("[STARTING] server is starting...")
start()发布于 2022-05-29 15:48:19
在字典中添加
clients[addr] = thread但是addr不是"10.14.0.1",而是('10.14.0.1', 52870),它设置
clients[ ('10.14.0.1', 52870) ] = thread您必须使用clients[ ('10.14.0.1', 52870) ]来访问clients中的元素。
但还有另外一个问题。
client保留了thread,但是您需要connection/socket来运行send()和recv(),所以您必须使用self.conn来实现这一点。
self.conn.send(...)我没有测试,但应该是这样的
import socket
import threading
import time
# --- constants ---
HEADER = 80
PORT = 9000
#SERVER = socket.gethostbyname(socket.gethostname())
SERVER = '0.0.0.0'
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
VITA_POSITIVE = "0000"
# --- classes ---
class ClientThread(threading.Thread):
def __init__(self, conn: socket.socket, addr: str):
super().__init__()
self.conn = conn
self.addr = addr
def send(self, msg: str):
self.conn.sendall(msg.encode())
def run(self):
print(f"[NEW CONNECTION] {self.addr} connected.")
connected = True
while connected:
self.conn.send("VITA".encode(FORMAT))
vita_response_iconet = self.conn.recv(HEADER).decode(FORMAT)
print(vita_response_iconet)
if vita_response_iconet == VITA_POSITIVE:
print("VITA received from Iconet")
vita_iconet = 1
else:
print("VITA not received from Iconet")
vita_iconet = 0
self.conn.send("VITA".encode(FORMAT))
vita_response_robot = self.conn.recv(HEADER).decode(FORMAT)
print(vita_response_robot)
if vita_response_iconet == VITA_POSITIVE:
print("VITA received from Robot")
vita_robot = 1
else:
print("VITA not received from Robot")
vita_robot = 0
if vita_iconet and vita_robot == 1:
my_timer = 0
else:
my_timer = my_timer
self.conn.close()
# --- functions ---
def start():
try:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# solution for "[Error 89] Address already in use". Use before bind()
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(ADDR)
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
print('wait for client')
conn, addr = server.accept()
print('interesting')
print(conn)
print(addr)
thread = ClientThread(conn, addr)
print ('be ready')
thread.start()
clients[addr] = thread
print(f"[ACTIVE CONNECTIONS] {threading.active_count() - 2}")
except KeyboardInterrupt:
print('Stopped by Ctrl+C')
finally:
server.close()
# --- main ---
#my_timer = 0
clients = {}
# I don't know why you run it in thread and later run normally as `start()`
#connections = threading.Thread(target=start)
#connections.start()
print("[STARTING] server is starting...")
start()https://stackoverflow.com/questions/72422475
复制相似问题