【发布时间】:2022-09-29 00:25:58
【问题描述】:
我有一个W5100S-EVB-Pico,它基本上是一个带有以太网端口的 Pi Pico。我想通过 TCP 套接字连接向它发送命令。基本上我想使用这个板通过以太网控制硬件。
- W5100 板应该是接受连接/命令的服务器。
- 我打算用 Python 编写一个 GUI 来发送命令
- 我正在运行this micropython version。
- Python 3.7 版
但这是现在的问题:下面的代码不断给我这个错误:\'操作系统错误:[Errno 107] ENOTCONN\'
- EDIT_01:似乎我从客户端关闭连接太快了()
- EDIT_02:我需要在关闭前得到服务器的某种确认吗?或者,有哪些可能的方式来实现这种通信?
谢谢阅读!
这是代码和对正在发生的事情的解释:
W5100-EVB-Pico 上的代码:
from machine import Pin, SPI
import network
import usocket as socket
# Only needed for static IP setup:
ip_address = \'192.168.1.20\'
subnet = \'255.255.255.0\'
gateway = \'192.168.1.1\'
dns = \'8.8.8.8\'
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_port = 8080
# Init ethernet
def init_ethernet():
spi = SPI(0, 2_000_000, mosi=Pin(19), miso=Pin(16), sck=Pin(18))
nic = network.WIZNET5K(spi, Pin(17), Pin(20))
# Static IP:
# nic.ifconfig((ip_address, subnet, gateway, dns))
# DHCP:
nic.active(True)
while not nic.isconnected():
pass
ip_address = nic.ifconfig()[0]
subnet = nic.ifconfig()[1]
gateway = nic.ifconfig()[2]
dns = nic.ifconfig()[3]
print(\'Connected:\')
print(\'IP \', ip_address)
print(\'Subnet \', subnet)
print(\'Gateway \', gateway)
print(\'DNS \', dns)
listen()
def listen():
server_socket.bind((ip_address, socket_port))
server_socket.listen(5)
print(f\'Listening on {ip_address} port {socket_port}\')
while True:
print(\'>>>This should print once and it does\')
print(\'>>>Waiting for connection\')
client, address = server_socket.accept()
print(f\'Client connected from: {address}\')
client.close()
if __name__ == \"__main__\":
init_ethernet()
运行时的输出是:
netif changed 192.168.1.20
Connected:
IP 192.168.1.20
Subnet 255.255.255.0
Gateway 192.168.1.1
DNS 192.168.1.150
Listening on 192.168.1.20 port 8080
>>>This should print once and it does
>>>Waiting for connection
我的 Python 代码:
import socket
local_IP = socket.gethostbyname(socket.gethostname())
port = 8080
server_ip = \'192.168.1.20\'
server_port = 8080
server_address = (server_ip, server_port)
def test_socket():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect(server_address)
message = \'Hello from client\'
s.sendall(bytes(message, encoding=\"utf-8\"))
if __name__ == \'__main__\':
test_socket()
一旦我运行此代码,W5100 的输出就是:
...
>>>This should print once and it does
>>>Waiting for connection
Traceback (most recent call last):
File \"<stdin>\", line 55, in <module>
File \"<stdin>\", line 37, in init_ethernet
File \"<stdin>\", line 49, in listen
OSError: [Errno 107] ENOTCONN
==============================================
- EDIT_01: 我发现当我在这里添加 \'time.sleep(1)\' 时:
s.sendall(bytes(message, encoding=\"utf-8\"))
time.sleep(1)
s.close()
错误不会发生。我是否在 Python 端过早地关闭了套接字?
==============================================
- EDIT_02:
我在服务器上更改了此代码:
while True:
print(\'>>>Waiting for connection\')
client, address = server_socket.accept()
print(f\'Client connected from: {address}\')
data = client.recv(1024).decode()
print(data)
client.close()
这在客户端:
def test_socket():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(server_address)
message = \'This is a really long message of many bytes and can\\n\' \\
\'even be some very long JSON data?\\n\' \\
\'which is pretty awesome!\\n\' \\
\'Man This is what I was after !!!\'
s.sendall(bytes(message, encoding=\"utf-8\"))
time.sleep(1)
s.close()
但是, time.sleep(1) 不是要走的路:(
我想我应该在服务器确认后关闭套接字? 欢迎任何提示和提示, 谢谢!
-
我发现当我在 \'s.sendall()\' 和 \'s.close()\' 之间添加 \'time.sleep(1)\' 时,它似乎(有点)工作?我的 Python 脚本是否过早关闭套接字?
标签: python sockets micropython