我正在学习 python 和 asyncio,在成功使用 asyncio 创建 TCP 客户端/服务器后,我第一次尝试使用 pyserial-asyncio 在 Raspberry Pi 5 上使用 Python 3.8(我无法更改版本)在 bash 中运行来创建串行客户端/服务器。
这是服务器:
import asyncio
import serial_asyncio
class UARTProtocol(asyncio.Protocol):
def __init__(self):
self.transport = None
def connection_made(self, transport):
self.transport = transport
print('Port opened', transport)
def data_received(self, data):
print('Data received:', data.decode())
# Echo received data back (example)
self.transport.write(data)
# Close the connection if 'exit' is received
if data == b"exit\r":
self.transport.close()
def connection_lost(self, exc):
print('Port closed')
self.transport = None
def pause_writing(self):
print('pause writing')
print(self.transport.get_write_buffer_size())
def resume_writing(self):
print(self.transport.get_write_buffer_size())
print('resume writing')
async def run_uart_server():
loop = asyncio.get_running_loop()
try:
transport, protocol = await serial_asyncio.create_serial_connection(loop, UARTProtocol, '/dev/ttyAMA2', baudrate=9600)
print("UART server started.")
await asyncio.Future() # Run forever
except serial.serialutil.SerialException as e:
print(f"Error: Could not open serial port: {e}")
finally:
if transport:
transport.close()
if __name__ == "__main__":
asyncio.run(run_uart_server())
和客户:
import asyncio
import serial_asyncio
async def uart_client(port, baudrate):
try:
reader, writer = await serial_asyncio.open_serial_connection(url=port, baudrate=baudrate)
print(f"Connected to {port} at {baudrate} bps")
async def receive_data():
while True:
try:
data = await reader.readline()
if data:
print(f"Received: {data.decode().strip()}")
except Exception as e:
print(f"Error reading data: {e}")
break
async def send_data():
while True:
message = input("Enter message to send (or 'exit' to quit): ")
if message.lower() == 'exit':
break
writer.write((message + '\n').encode())
# writer.write_eof()
await writer.drain()
print(f"Sent: {message}")
await asyncio.gather(receive_data(), send_data())
except serial.SerialException as e:
print(f"Error opening serial port: {e}")
finally:
if 'writer' in locals():
writer.close()
await writer.wait_closed()
print("Connection closed.")
if __name__ == "__main__":
asyncio.run(uart_client('/dev/ttyAMA1', 9600))
我希望客户端提示我输入一些文本,然后立即将其发送到服务器并打印出来。我可以让客户端提示我输入文本,但服务器不会显示任何文本,直到我exit
在客户端输入以关闭连接后,服务器才会打印我在客户端循环中输入的所有文本。
除其他事项外,我还尝试添加writer.write_eof()
客户端(请参阅下面客户端代码中注释掉的行),并且成功使服务器立即显示来自客户端的前面的文本,但客户端再也没有提示我输入。
如果我运行服务器并且只echo foo > /dev/ttyAMA1
从 bash 执行操作,服务器就会foo
立即打印,所以我怀疑问题出在客户端。
我做错什么了?