gpt4 book ai didi

python-3.x - 按下 "Ctrl+C"时 python 回显服务器的 Unicode 错误

转载 作者:行者123 更新时间:2023-12-03 09:00:28 26 4
gpt4 key购买 nike

我已经创建了 python 回显服务器。可以使用命令启动回显服务器

sudo python3.8 echo_server.py

客户端可以使用命令连接到它

telnet localhost 5000

我已经实现了一些命令,如时间、退出和网络(即,如果您在 telnet 客户端上键入“时间”命令,服务器将以系统时间响应。)

“网络”命令包含 3 个 while 循环(即 1 个循环用于选择网络类型,2 个循环用于选择静态\动态,3 个循环用于配置 wifi 设置的 ssid/密码)。现在在配置 ssid/pwd 时,我想按“Ctrl+c”返回到 telnet 客户端的主命令提示符(即我们可以输入时间、网络命令的地方)。但是我无法处理回显服务器上的“Ctrl+c”。在 telnet 客户端上按下“Ctrl+c”时出现异常

Exception in thread MyThread:
Traceback (most recent call last):
File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "echo_server.py", line 47, in run
tx_data = ""
File "/usr/lib/python3.8/codecs.py", line 322, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
Main Terminating...

请找到我的 echo_server.py 文件

import socket
import os
import os.path
import subprocess
import time
from subprocess import Popen, PIPE, STDOUT
from threading import Thread
from time import sleep

class MyThread(Thread):
def __init__(self, val):
''' Constructor. '''
Thread.__init__(self)
self.val = val

class Filter:
"""Substitute \n with \r\n in stream output to terminal."""

def __init__(self, file):
self.file = file

def write(self, data):
self.file.write(data.replace("\n", "\r\n"))

def run(self):

while True:
HOST = '' # Symbolic name meaning all available interfaces
PORT = 5000 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
s.bind((HOST, PORT))
s.listen(5)
except socket.error:
time.sleep(5)
continue
conn, addr = s.accept()
file = conn.makefile(mode="rw")
filtered_file =MyThread.Filter(file)
file.flush()
filtered_file.write("Enter 'help' to list all valid commands\n")
while True:
file.write("Command> ")
file.flush()
data = file.readline()
tx_data = ""
if not data: break
data = data.strip()
if not data:
continue
elif data == 'time':
f= os.popen('date')
date=f.read().strip()
tx_data = date + '\n'

elif data == "network":

while True:
file.write("1. WiFi\n")
file.flush()
file.write("2. Ethenet\n")
file.flush()
file.write("3. Exi\n")
file.flush()
file.write("Enter a choice:")
file.flush()
choice = file.readline()
choice = choice.strip()
if choice == "1":
while True:
file.write("1. DHCP\n")
file.flush()
file.write("2. Static\n")
file.flush()
file.write("3. Exit\n")
file.flush()
file.write("Enter a choice:")
file.flush()
subchoice = file.readline()
subchoice = choice.strip()
if subchoice == "1":
while True:
file.write("Enter ssid:")
file.flush()
ssid = file.readline()
ssid = ssid.strip()
file.write("Enter pwd:")
file.flush()
pwd = file.readline()
pwd = pwd.strip()
break
break
elif choice == "2":
break
elif choice == "3":
break
else:
break

elif data == 'help':
tx_data = '''Valid commands are as below:
Enter number against the command for execution

1. time
2. network
3. exit\n'''

elif data == 'exit':
break

else:
tx_data = "Unknown Command: " + data + \
"\nEnter 'help' for list of valid commands\n"

filtered_file.write(tx_data)
#print 'Closing connection with client'
file.close()
conn.close()


# Run following code when the program starts
if __name__ == '__main__':
# Declare objects of My Thread class
my_obj = MyThread(4)
my_obj.setName('MyThread')


# Start running the threads!
my_obj.start()

# Wait for the threads to finish...
my_obj.join()

print('Main Terminating...')

我不确定如何处理“Ctrl+c”,以便在我们可以输入命令时控制回到提示符处。如果有人有任何解决此问题的建议,请告诉我。

最佳答案

这是我的程序版本:

# echo_server.py
import socket
import os
import os.path
import subprocess
import time
from subprocess import Popen, PIPE, STDOUT
from threading import Thread
from time import sleep

def getcommand(thisfile, thisprompt, stripped=True):
thisfile.write(thisprompt)
thisfile.flush()
command = thisfile.readline()[:-1]
# print(f"{len(command)} chars received") # just for debug
# for i in command:
# print(ord(i))
if stripped:
return command.strip()
return command


class MyThread(Thread):
def __init__(self, val):
''' Constructor. '''
Thread.__init__(self)
self.val = val

class Filter:
"""Substitute \n with \r\n in stream output to terminal."""

def __init__(self, file):
self.file = file

def write(self, data):
self.file.write(data.replace("\n", "\r\n"))

def run(self):

while True:
HOST = '' # Symbolic name meaning all available interfaces
PORT = 5000 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
s.bind((HOST, PORT))
s.listen(5)
except socket.error:
time.sleep(5)
continue
conn, addr = s.accept()
file = conn.makefile(mode="rw", encoding="UTF-8", errors="ignore")
filtered_file = MyThread.Filter(file)
file.flush()
filtered_file.write("Enter 'help' to list all valid commands\n")
while True:
data = getcommand(file, "Command> ", stripped=False)
tx_data = ""
if not data:
print("No Command!")
break # closing connection
data = data.strip()
if not data:
print("Just Spaces!")
continue

elif data == 'time':
f= os.popen('date')
date=f.read().strip()
tx_data = date + '\n'

elif data == "network":
while True:
file.write("1. WiFi\n")
file.flush()
file.write("2. Ethernet\n")
file.flush()
file.write("3. Exit\n")
file.flush()
choice = getcommand(file, "Enter a choice:")
if choice == "1":
while True:
file.write("1. DHCP\n")
file.flush()
file.write("2. Static\n")
file.flush()
file.write("3. Exit\n")
file.flush()
subchoice = getcommand(file, "Enter a choice:")
if subchoice == "1":
while True:
ssid = getcommand(file, "Enter ssid:")
pwd = getcommand(file, "Enter password:")
if ssid and pwd:
break
break
elif choice == "2":
break
elif choice == "3":
break

elif data == 'help':
tx_data = '''Valid commands are as below:
Enter number against the command for execution

1. time
2. network
3. exit\n'''

elif data == 'exit':
break

else:
tx_data = "Unknown Command: " + data + \
"\nEnter 'help' for list of valid commands\n"

filtered_file.write(tx_data)
print('Closing connection with client')
file.close()
conn.close()


# Run following code when the program starts
if __name__ == '__main__':
# Declare objects of My Thread class
my_obj = MyThread(4)
my_obj.setName('MyThread')


# Start running the threads!
my_obj.start()

# Wait for the threads to finish...
my_obj.join()

print('Main Terminating...')

我创建了一个新函数来处理来自终端的文本输入。此函数去除由 readline() 附加的新行字符,并可选择去除输入字符串中的前导和尾随空白。这使您可以选择在用户未输入任何数据时关闭连接,而在他/她只是输入空格时保持连接打开并重复提示。我还在 conn.makefile() 中使用了 'errors' 可选参数,以避免 UnicodeDecodeError,并添加了一行以重复输入 ssid 和密码(如果其中任何一个为空)。当主要选择是“网络”时,我还删除了 else 子句,让用户只能通过选择 3 来退出。使用此版本,无需使用 Ctrl-C(也有键盘中断的含义),如果用户输入它,它不会再中断服务器。现在,如果您在客户端中按 Ctrl-C,您将停止接收服务器的输出,但如果您盲目地输入“退出”选项,您可以优雅地退出连接。

关于python-3.x - 按下 "Ctrl+C"时 python 回显服务器的 Unicode 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62222803/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com