我有一个完全工作的esp芯片连接到wifi并创建一个服务器。当我发送一个OTA命令时,它运行一个使用套接字连接下载文件的函数。
这是我正在使用的upgradeder.lua:
--------------------------------------
-- Upgrader module for NODEMCU
-- LICENCE: http://opensource.org/licenses/MIT
-- cloudzhou<wuyunzhou@espressif.com> - Heavily modified by aschmois
--------------------------------------
--[[
update('file.lua', 'http://IP.ADRESS/path/file.lua')
]]--
local header = ''
local isTruncated = false
local function save(filename, response)
if isTruncated then
file.write(response)
return
end
header = header..response
local i, j = string.find(header, '\r\n\r\n')
if i == nil or j == nil then
return
end
prefixBody = string.sub(header, j+1, -1)
file.write(prefixBody)
header = ''
isTruncated = true
return
end
----
function update(filename, url, cn)
local tmpError = nil
local running = true
local error = nil
local success = false
print("Downloading from: " .. url)
local ip, port, path = string.gmatch(url, 'http://([0-9.]+):?([0-9]*)(/.*)')()
if ip == nil then
return false
end
if port == nil or port == '' then
port = 80
end
port = port + 0
if path == nil or path == '' then
path = '/'
end
print("-- Detailed Connection Info --")
print("IP: ".. ip)
print("Port: ".. port)
print("Path: ".. path)
print("-- END --")
local function timeout()
error = tmpError
file.remove(filename)
conn:close()
running = false
end
conn = net.createConnection(net.TCP, false)
conn:on('connection', function(sck, response)
tmr.stop(1)
file.open(filename, 'w')
conn:send('GET '..path..' HTTP/1.0\r\nHost: '..ip..'\r\n'..'Connection: close\r\nAccept: */*\r\n\r\n')
tmpError = "READ TIMEOUT"
tmr.alarm(1, 10000, 0, timeout)
end)
conn:on('receive', function(sck, response)
tmr.stop(1)
tmpError = "READ(2) TIMEOUT"
tmr.alarm(1, 10000, 0, timeout)
print(response)
save(filename, response)
end)
conn:on('disconnection', function(sck, response)
tmr.stop(1)
local function reset()
local list = file.list()
for k,v in pairs(list) do
if(filename == k) then
if(v == 0) then
success = false
file.close()
file.remove(filename)
else
file.close()
success = true
end
end
end
print(header)
header = ''
isTruncated = false
if(success) then
print(filename..' saved')
else
print("Could not download `".. filename.."`")
end
running = false
end
tmr.alarm(0, 2000, 0, reset)
end)
conn:connect(port, ip)
tmpError = "CONN TIMEOUT"
tmr.alarm(1, 10000, 0, timeout)
tmr.alarm(2, 1000, 1, function()
if(running == false) then
tmr.stop(2)
local buf = ''
if(success) then
buf = buf.."HTTP/1.1 200 OK\r\nServer: WiFi Relay\r\nContent-Type: text/plain\r\n\r\n"
buf = buf.."1"
else
buf = buf.."HTTP/1.1 500\r\nServer: WiFi Relay\r\nContent-Type: text/plain\r\n\r\n"
buf = buf.."0"
buf = buf.."\n"
if(error ~= nil) then
buf = buf..error
else
buf = buf.."UNKNOWN ERROR"
end
end
cn:send(buf)
cn:close()
end
end)
return true
end
作为测试我发送它:filename = rz.lua和url = http://192.168.1.132/rz.lua。 cn变量是将信息发送回客户端的连接。
esp芯片打印:
Downloading from: http://192.168.1.132/rz.lua
-- Detailed Connection Info --
IP: 192.168.1.132
Ò_ÇRöfJSúfÊÃjêÐÿ (junk reset data)
问题似乎与conn:send()命令有关。如果它在on connect功能中,则重置。如果它在外面,我将得到读取超时(因为从未调用读取)。我真的不知道还能做什么。
这是ESP固件信息:
NodeMCU custom build by frightanic.com
branch: master
commit: 93421f2702fb02ce169f82f96be7f2a8865511e1
SSL: false
modules: node,file,gpio,wifi,net,tmr,uart
答案 0 :(得分:2)
您正在重置。 &#34;垃圾&#34;是波特率错误的BootROM消息。
请勿在同一回调中执行发送后关闭。使用开(&#39;已发送&#39;,...)来触发关闭。因此,警报2回调的21行主体将更好地编写:
local response = "HTTP/1.1 200 OK\r\nServer: WiFi Relay\r\nContent-Type: text/plain\r\n\r\n%s"
cn:send(response:format(success and "1" or ("0\n\r" .. (error or "UNKNOWN ERROR")))
cn:on('sent', function(cn) cn:close() end)
在那个注意事项上你的27行断开回调会写得更好:
tmr.stop(1)
tmr.alarm(0, 2000, 0, function()
local len = file.list()(filename)
success = len and len > 0
file.close()
if not success then file.remove(filename)
file.flush()
end)
请注意,在写入或删除文件后刷新SPIFFS总是明智的。
您使用标准模式,所以为什么不封装它:
local conn = net.createConnection(net.TCP, false)
local function setTimeout(reason)
-- tmr.stop(1) -- not needed is the next line resets the alarm
tmr.alarm(1, 10000, 0, function ()
-- you don't need tmpError as reason is a local and bound as an upval
error, running = reason, false
file.remove(filename) file.flush()
return conn:close()
end)
end
我可以继续,但我把它留给你。稍加思考,您的代码将是大小的三分之一,更具可读性。
答案 1 :(得分:0)
我无法确定但问题似乎是内存错误(因为没有恐慌所以很奇怪)所以这就是我所做的修复它:
local request = table.concat({"GET ", path,
" / HTTP/1.1\r\n",
"Host: ", ip, "\r\n",
"Connection: close\r\n",
"Accept: */*\r\n",
"User-Agent: Mozilla/4.0 (compatible; esp8266 Lua;)",
"\r\n\r\n"})
conn = net.createConnection(net.TCP, false)
conn:on('connection', function(sck, response)
tmr.stop(1)
tmpError = "READ TIMEOUT"
tmr.alarm(1, 10000, 0, timeout)
conn:send(request)
end)
我使用table.concat方法创建了请求,并使用表而不是一个大字符串。希望这能帮助那些有需要的人。