首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python-Micropython TCP套接字在w5100-EVB-Pico上

Python-Micropython TCP套接字在w5100-EVB-Pico上
EN

Stack Overflow用户
提问于 2022-09-26 17:40:21
回答 1查看 124关注 0票数 0

我有一个W5100S-EVB-Pico,它基本上是一个带有以太网端口的Pi Pico。我想通过TCP套接字连接向它发送命令。基本上,我想用这个板控制以太网上的硬件。

  • W5100板应该是接受连接/命令的服务器。
  • 我计划用Python编写GUI以发送命令
  • 我在上面运行这个micropython版本
  • Python版本3.7

但现在的问题是:下面的代码一直给我错误:'OSError: Errno 107ENOTCONN

  • EDIT_01:似乎我从客户端()关闭连接太快了
  • EDIT_02:在关闭之前,我需要服务器确认吗?或者,实现这种交流的可能方法是什么?

感谢您的阅读!

下面是代码和对正在发生的事情的解释:

W5100-EVB-Pico上的代码:

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

运行此命令时的输出是:

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

代码语言:javascript
复制
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的输出是:

代码语言:javascript
复制
...
>>>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)‘时:
代码语言:javascript
复制
s.sendall(bytes(message, encoding="utf-8"))
time.sleep(1)
s.close()

此错误不会发生。我是不是在Python方面关闭套接字太快了?

=============================================

  • EDIT_02:

我在服务器上更改了以下代码:

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

客户上的这个:

代码语言:javascript
复制
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)并不适合:(

我想我应该在服务器确认后关闭套接字?欢迎任何提示和提示,谢谢!

EN

回答 1

Stack Overflow用户

发布于 2022-09-28 16:25:58

好的,关键似乎是在通信中捕捉错误。

这个客户端代码的工作方式和预期一样..。就目前而言。

代码语言:javascript
复制
import socket
import json

local_IP = socket.gethostbyname(socket.gethostname())
port = 8080

server_ip = '192.168.1.20'
server_port = 8080
server_address = (server_ip, server_port)

commands = [['A', 1, '1234567890_1234567890_1234567890'],
            ['B', 2, 'hello'],
            ['C', 3.7],
            ['D', 4]]

def test_socket():

    for c in commands:
        send(json.dumps(c))


def send(message):

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(server_address)

    s.sendall(bytes(message, encoding="utf-8"))

    try:
        received_data, addr = s.recvfrom(128)
        print(received_data, addr)
        print(received_data.decode('utf-8'))
    except socket.error as error:
        print(f'Socket error: {error.errno}')
    finally:
        pass


if __name__ == '__main__':

    test_socket()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73857928

复制
相关文章

相似问题

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