本站改版新增arduino频道
import socket
import network
import uos
import errno
from uio import IOBase
last_client_socket = None
server_socket = None
# Provide necessary functions for dupterm and replace telnet control characters that come in.
class TelnetWrapper(IOBase):
def __init__(self, socket):
self.socket = socket
self.discard_count = 0
def readinto(self, b):
readbytes = 0
for i in range(len(b)):
try:
byte = 0
# discard telnet control characters and
# null bytes
while(byte == 0):
byte = self.socket.recv(1)[0]
if byte == 0xFF:
self.discard_count = 2
byte = 0
elif self.discard_count > 0:
self.discard_count -= 1
byte = 0
b[i] = byte
readbytes += 1
except (IndexError, OSError) as e:
if type(e) == IndexError or len(e.args) > 0 and e.args[0] == errno.EAGAIN:
if readbytes == 0:
return None
else:
return readbytes
else:
raise
return readbytes
def write(self, data):
# we need to write all the data but it's a non-blocking socket
# so loop until it's all written eating EAGAIN exceptions
while len(data) > 0:
try:
written_bytes = self.socket.write(data)
data = data[written_bytes:]
except OSError as e:
if len(e.args) > 0 and e.args[0] == errno.EAGAIN:
# can't write yet, try again
pass
else:
# something else...propagate the exception
raise
def close(self):
self.socket.close()
# Attach new clients to dupterm and
# send telnet control characters to disable line mode
# and stop local echoing
def accept_telnet_connect(telnet_server):
global last_client_socket
if last_client_socket:
# close any previous clients
uos.dupterm(None)
last_client_socket.close()
last_client_socket, remote_addr = telnet_server.accept()
print("Telnet connection from:", remote_addr)
last_client_socket.setblocking(False)
# dupterm_notify() not available under MicroPython v1.1
# last_client_socket.setsockopt(socket.SOL_SOCKET, 20, uos.dupterm_notify)
last_client_socket.sendall(bytes([255, 252, 34])) # dont allow line mode
last_client_socket.sendall(bytes([255, 251, 1])) # turn off local echo
uos.dupterm(TelnetWrapper(last_client_socket))
def stop():
global server_socket, last_client_socket
uos.dupterm(None)
if server_socket:
server_socket.close()
if last_client_socket:
last_client_socket.close()
# start listening for telnet connections on port 23
def start(port=23):
stop()
global server_socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
ai = socket.getaddrinfo("0.0.0.0", port)
addr = ai[0][4]
server_socket.bind(addr)
server_socket.listen(1)
server_socket.setsockopt(socket.SOL_SOCKET, 20, accept_telnet_connect)
for i in (network.AP_IF, network.STA_IF):
wlan = network.WLAN(i)
if wlan.active():
print("Telnet server started on {}:{}".format(wlan.ifconfig()[0], port))import utelnetserver utelnetserver.start()
utelnetserver
这是 telnet 服务器的简单实现,它将 telnet 客户端连接到 REPL。telnet 服务器和关联的逻辑在后台运行,因此您可以使用 REPL 或使用它运行其他脚本。一次支持单个客户端连接。
更新为支持 MPY v1.1。
要开始使用它,只需将以下内容添加到您的boot.py
import utelnetserver
utelnetserver.start()
在引导时,您应该看到类似下面的内容:Telnet server started on 192.168.2.119:23
我只在Mac上使用telnet客户端对其进行了测试,但有了它,它就变得简单了:
$ telnet 192.168.2.119
Trying 192.168.2.119...
Connected to esp_f4b4b3.
Escape character is '^]'.
>>> print("Hello!")
Hello!
局限性
一次一个 telnet 客户端
无身份验证支持
支持的内容
Telnet 服务器是基于回调的
通过远程登录客户端与 REPL 交互
其他示例
utelnetserver模块非常简单,提供,因此您可以根据需要启动/停止它,或者在与telnet的典型端口23不同的端口上运行它。start(port=23)stop()
开源地址:https://github.com/cpopp/MicroTelnetServer
Copyright © 2014 ESP56.com All Rights Reserved
晋ICP备14006235号-22 晋公网安备14108102001165号
执行时间: 0.009666919708252 seconds