我正在尝试组装一个简单的温度计,该温度计可在 OLED 显示屏上提供温度,并使用 MicroPython 通过 ESP8266 上的 http 请求提供温度。
轮询对象已用于防止 websocket 阻塞循环(因此可以更新测量值和 OLED 显示)。< /p>
#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()
它似乎在一段时间内运行良好,但我发现了两个问题,非常感谢您的帮助:
MPY: soft reboot Connection successful ('192.168.1.74', '255.255.255.0', '192.168.1.1', '192.168.1.1') b'29.0,24.0' Got an incoming connection request Start processing Got a connection from ('192.168.1.64', 58581) 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', 58582) 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', 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. >>>
第 104 行对应于:
conn.sendall(response)
谢谢!
答案 0 :(得分:1)
即使我只连接到它一次,2 或 3 个请求在 shell 终端中显示为已收到,如下所示。为什么会发生这种情况,我该如何解决?是否可以让浏览器等待足够长的时间来发送第二个或第三个请求?
这取决于浏览器如何连接到您的服务器。浏览器可能正在寻找多个请求,或者浏览器具有连接到服务器的套接字的超时值。我没有任何网络知识,但看起来像是对不同信息的两个请求。该信息的处理方式应传递到 web_page()
。您发送的似乎是整个网页,而不是它要查找的具体内容。
运行一段时间后,我将无法再连接到它,因为它不会响应。我的方法有什么明显的问题吗?
可能发生的情况是您有 socket.sendall()
阻止创建任何新套接字。另请注意,即使您已正确关闭套接字,该套接字仍可能有数据要发送。它已被标记为关闭,但操作系统可能尚未将其关闭。
您使用 select.poll()
走在正确的轨道上。乍一看,使用 serverSocket
(select.poll) 注册您的 pollerObject
似乎可以处理未来的连接。这不是正在发生的事情。您只向 pollerObject
注册了一个套接字。 severSocket
正在为来自浏览器的传入连接获取 select.POLLIN
事件。您需要一种方法将 serverSocket
创建的新套接字添加/注册到 pollerObject
,以便为其他套接字提供服务。
现在你在 micropython 中尝试做的最好的例子是制作类似于 Python 3 Selectors 中的选择器示例的东西。
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)
通常,您不必担心用 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 子句来处理此问题。