Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Esp8266 MicroPython中使用轮询的非阻塞服务器套接字问题_Esp8266_Micropython_Usocket - Fatal编程技术网

Esp8266 MicroPython中使用轮询的非阻塞服务器套接字问题

Esp8266 MicroPython中使用轮询的非阻塞服务器套接字问题,esp8266,micropython,usocket,Esp8266,Micropython,Usocket,我正在尝试组装一个简单的温度计,它可以提供OLED显示屏上的温度,也可以通过使用MicroPython的ESP8266上的http请求提供温度 轮询器对象用于防止websocket阻塞环路,以便更新测量和OLED显示 #CREATE SOCKET serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serverSocket.bind(('', 80)) serverSocket.listen(5) #REGISTER

我正在尝试组装一个简单的温度计,它可以提供OLED显示屏上的温度,也可以通过使用MicroPython的ESP8266上的http请求提供温度

轮询器对象用于防止websocket阻塞环路,以便更新测量和OLED显示

#CREATE SOCKET
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.bind(('', 80))
serverSocket.listen(5)

#REGISTER SOCKET TO THE POLLER
pollerObject = select.poll()
pollerObject.register(serverSocket, select.POLLIN)

#PERFORM FIRST MEASUREMENT AT STARTUP
last_meas_time = startup_time
sensor_readings = read_sensor()
print(sensor_readings)
display.display_measurement(str(temp),str(hum))

#LOOP FOREVER
while True:
    
    #ONE MEASUREMENT UPDATE EVERY 30s
    if(time.time() - last_meas_time >= 30):
        sensor_readings = read_sensor()
        print(sensor_readings)
        display.display_measurement(str(temp),str(hum))
        last_meas_time = time.time()
    
    #WAIT UP TO 10s FOR INCOMING CONNECTIONS
    fdVsEvent = pollerObject.poll(10000)
    
    for descriptor, Event in fdVsEvent:
        print()
        print("Got an incoming connection request")
        print("Start processing")
        # Do accept() on server socket or read from a client socket
        conn, addr = serverSocket.accept()
        print('Got a connection from %s' % str(addr))
        request = conn.recv(1024)
        print('Content = %s' % str(request))
        response = web_page()
        conn.send('HTTP/1.1 200 OK\n')
        conn.send('Content-Type: text/html\n')
        conn.send('Connection: close\n\n')
        conn.sendall(response)
        conn.close()
一段时间以来,它似乎运行良好,但我发现它存在两个问题,非常感谢您的帮助:

即使我只连接到它一次,2或3个请求在shell终端中显示为已接收,如下所示。为什么会发生这种情况?我该如何解决?浏览器是否可以等待足够长的时间来发送第二个或第三个请求? 谢谢

即使我只连接到它一次,2或3个请求在shell终端中显示为已接收,如下所示。为什么会发生这种情况?我该如何解决?浏览器是否可以等待足够长的时间来发送第二个或第三个请求

这取决于浏览器如何连接到服务器。浏览器可能正在查找多个请求,或者浏览器具有连接到服务器的套接字的超时值。我没有任何网络知识,但它看起来像两个不同的信息请求。这些信息是如何处理的,应该传递到网页上。看起来您发送的是整个网页,而不是它要查找的特定内容

经过长时间运行后,我将无法再连接到它,因为它将不会响应。我的方法有什么明显的问题吗

可能发生的情况是socket.sendall阻止创建任何新套接字。另外请注意,即使已正确关闭套接字,套接字仍可能有数据要发送。它已被标记为关闭,但操作系统可能尚未关闭它

通过使用select.poll,您的思路是正确的。乍一看,似乎使用pollerObject select.poll注册serverSocket可以处理将来的连接。事实并非如此。您只向pollerObject注册了一个套接字。severSocket正在从浏览器获取传入连接的select.POLLIN事件。您需要一种将serverSocket创建的新套接字添加/注册到pollerObject的方法,以便为其他套接字提供服务

现在,在micropython中尝试做的最好的示例是制作类似于中选择器示例的东西

通常,您不必担心用socket.send填充套接字传输缓冲区,但您应该处理它。现在,我会在socket.sendall之前和之后放置一些调试打印,因为这将阻止/重试,直到发送所有数据。如果并非所有数据都已发送,则必须为写准备事件注册套接字,并传递需要发送的其余数据。这有点复杂

Got an incoming connection request
Start processing
Got a connection from ('192.168.1.64', 59160)
Content = b''
Traceback (most recent call last):
  File "main.py", line 104, in 
OSError: [Errno 104] ECONNRESET
MicroPython v1.13 on 2020-09-11; ESP module with ESP8266
Type "help()" for more information.
>>> 
您在上面遇到的问题是,您的套接字连接可能已超时。TCP正在让您知道连接已过期。您应该使用try-except-else子句来处理此问题

Got an incoming connection request Start processing Got a connection from ('192.168.1.64', 59158) Content = b'GET / HTTP/1.1\r\nHost: 192.168.1.74\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nDNT: 1\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: pt-BR,pt;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,sv;q=0.5\r\n\r\n' Got an incoming connection request Start processing Got a connection from ('192.168.1.64', 59157) Content = b'GET /favicon.ico HTTP/1.1\r\nHost: 192.168.1.74\r\nConnection: keep-alive\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66\r\nDNT: 1\r\nAccept: image/webp,image/apng,image/*,*/*;q=0.8\r\nReferer: http://192.168.1.74/\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: pt-BR,pt;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,sv;q=0.5\r\n\r\n' Got an incoming connection request Start processing Got a connection from ('192.168.1.64', 59160) Content = b'' Traceback (most recent call last): File "main.py", line 104, in OSError: [Errno 104] ECONNRESET MicroPython v1.13 on 2020-09-11; ESP module with ESP8266 Type "help()" for more information. >>>
        conn.sendall(response)
import selectors
import socket

sel = selectors.DefaultSelector()

def accept(sock, mask):
    conn, addr = sock.accept()  # Should be ready
    print('accepted', conn, 'from', addr)
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read)

def read(conn, mask):
    data = conn.recv(1000)  # Should be ready
    if data:
        print('echoing', repr(data), 'to', conn)
        conn.send(data)  # Hope it won't block
    else:
        print('closing', conn)
        sel.unregister(conn)
        conn.close()

sock = socket.socket()
sock.bind(('localhost', 1234))
sock.listen(100)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)

while True:
    events = sel.select()
    for key, mask in events:
        callback = key.data
        callback(key.fileobj, mask)
Got an incoming connection request
Start processing
Got a connection from ('192.168.1.64', 59160)
Content = b''
Traceback (most recent call last):
  File "main.py", line 104, in 
OSError: [Errno 104] ECONNRESET
MicroPython v1.13 on 2020-09-11; ESP module with ESP8266
Type "help()" for more information.
>>>