尝试访问客户端时的KeyError

发布于 2025-02-02 12:08:00 字数 2999 浏览 2 评论 0原文

我有一个代码,需要执行从特定客户端发送和接收消息的任务。当我在服务器的发送函数中提及客户端地址时,我将获得关键错误。

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

i have a code which needs to perform the task of sending and receiving messages from specific clients. When i mention the client address in the send function of the server, i am being given a key error.

[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'

I have checked the dictionary by printing it and the client address does exist in it, i am not sure where i am making a mistake. Here is the code and any help would be tremendously appreciated.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

愁杀 2025-02-09 12:08:00

添加到字典中

clients[addr] = thread

您使用addr不是“ 10.14.0.1”('10.14.0.1',52870)

clients[ ('10.14.0.1', 52870) ] = thread

, 然后必须使用客户端[('10 .14.0.1',52870)]来访问clients中的元素。

但是还有其他问题。

客户端保留线程,但是您需要连接/套接字运行send> send> 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()

You add to dictionary using

clients[addr] = thread

but addr is not "10.14.0.1" but ('10.14.0.1', 52870) and it sets

clients[ ('10.14.0.1', 52870) ] = thread

and you would have to use clients[ ('10.14.0.1', 52870) ] to access element in clients.

But there is other problem.

client keeps thread but you need connection/socket to run send() and recv() - so you have to use self.conn for this.

self.conn.send(...)

I didn't test it but it should be something like this

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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文