首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试访问客户端时的KeyError

尝试访问客户端时的KeyError
EN

Stack Overflow用户
提问于 2022-05-29 09:32:37
回答 1查看 508关注 0票数 -1

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

代码语言:javascript
复制
[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'

我通过打印字典查过字典,其中确实存在客户地址,我不知道我在哪里出错。这是代码和任何帮助将不胜感激。

代码语言:javascript
复制
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()
EN

回答 1

Stack Overflow用户

发布于 2022-05-29 15:48:19

在字典中添加

代码语言:javascript
复制
clients[addr] = thread

但是addr不是"10.14.0.1",而是('10.14.0.1', 52870),它设置

代码语言:javascript
复制
clients[ ('10.14.0.1', 52870) ] = thread

您必须使用clients[ ('10.14.0.1', 52870) ]来访问clients中的元素。

但还有另外一个问题。

client保留了thread,但是您需要connection/socket来运行send()recv(),所以您必须使用self.conn来实现这一点。

代码语言:javascript
复制
self.conn.send(...)

我没有测试,但应该是这样的

代码语言:javascript
复制
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()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72422475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档