【问题标题】:PANIC: unprotected error in call to Lua API (wificonfig.lua:33: address in use)PANIC:调用 Lua API 时出现不受保护的错误(wificonfig.lua:33:正在使用的地址)
【发布时间】:2017-05-07 22:05:47
【问题描述】:

我正在尝试使用 frightanic.com 的 NodeMCU 自定义构建,使用 lua 在 ESP8266 上创建本地 http 服务器。

当我创建一个本地 http 服务器以及一个已经在端口 80 上侦听并从我的服务器站点获取数据的连接时,它给了我 PANIC 错误。

这是我的代码:

wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","password")
wifi.sta.connect()

tmr.alarm(1,10000, 1, function()
    if (wifi.sta.getip() == nil) then
        print("IP unavaiable, Waiting...")
    else
        foo()
        local_server()
    end
end)


function foo()
        conn = nil
        conn=net.createConnection(net.TCP,0)
        conn:on("receive", function(conn, payload)
            print("payload : "..#payload);
        end)
        conn:connect(80,"server.co.in")
        conn:on("connection", function(conn, payload)
            conn:send("GET /mypage?id=deadbeef HTTP/1.0\r\nHost: server.co.in\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n") end)

        conn:on("sent",function(conn)
                print("Closing server connection")
                conn:close()
            end)
end

function local_server()
    srv=net.createServer(net.TCP)
    srv:listen(80,function(conn)
        conn:on("receive", function(client,request)
            local buf = "Hello world";
            client:send('HTTP/1.0\n\n')
            client:send('<!DOCTYPE HTML>\n')
            client:send('<html>\n')
            client:send('<head><meta  content="text/html; charset=utf-8">\n')
            client:send('<title>Local server</title></head>\n')
            client:send('<style>body{ background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }</style>\n";')
            client:send(buf);

            conn:on("sent",function(conn)
                srv:close() -- Even tried with client:close()
            end)
        end)
    end)

end

这是不可能的吗?如果是,那我该怎么做?

如果我在计时器内创建一次服务器,则它不会创建任何本地服务器,即。我无法打开我的本地服务器 192.168.x.y。

这是我修改后的代码:

wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","password")
wifi.sta.connect()

tmr.alarm(1,10000, 1, function()
    if (wifi.sta.getip() == nil) then
        print("IP unavaiable, Waiting...")
    else
        print("Creating a server");
        srv=net.createServer(net.TCP,0)
        srv:listen(80,function(conn) 
        end)
        tmr.stop(1)
        tmr.alarm(1,10000, 1, function() 
              foo()
              local_server()
        end)
    end
end)


function foo()
        conn = nil
        conn=net.createConnection(net.TCP,0)
        conn:on("receive", function(conn, payload)
            print("payload : "..#payload);
        end)
        conn:connect(80,"server.co.in")
        conn:on("connection", function(conn, payload)
            conn:send("GET /mypage?id=deadbeef HTTP/1.0\r\nHost: server.co.in\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n") end)

        conn:on("sent",function(conn)
                print("Closing server connection")
                conn:close()
            end)
end

function local_server()
        conn:on("receive", function(client,request)
            local buf = "Hello world";
            client:send('HTTP/1.0\n\n')
            client:send('<!DOCTYPE HTML>\n')
            client:send('<html>\n')
            client:send('<head><meta  content="text/html; charset=utf-8">\n')
            client:send('<title>Local server</title></head>\n')
            client:send('<style>body{ background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }</style>\n";')
            client:send(buf);

            conn:on("sent",function(conn)
                srv:close() -- Even tried with client:close()
            end)
        end)
end

【问题讨论】:

    标签: lua esp8266 httpserver nodemcu panic


    【解决方案1】:
            client:send('HTTP/1.0\n\n')
    

    这不是一个有效的 HTTP 响应。服务于 HTML 页面的响应至少应如下所示

     HTTP/1.0 200 ok\r\n
     Content-type: text/html\r\n
     \r\n
     here comes the HTML body
    

    但这可能不是恐慌的原因,因为它抱怨地址正在使用中。我对 ESP8266 上运行的操作系统一无所知,但通常这个错误意味着已经有一个套接字绑定到这个地址和端口,并且你不能在同一位置有另一个套接字。因此,如果该系统上已经有一个 Web 服务器在运行,那么您将无法在同一地址启动另一个 Web 服务器。

    如果您已成功启动服务器一次,但无法通信(由于服务器的 HTTP 响应不正确)然后尝试再次重新启动服务器,也会发生此类错误:您需要一些时间才能重用与此套接字建立连接后,您可能需要等待几分钟才能再次启动服务器(或只是重新启动系统)。

    仔细查看您的代码,您会发现服务器是从计时器内部启动的:

    tmr.alarm(1,10000, 1, function()
    ...
            local_server()
    

    快速查看the documentation of tmr,您似乎正在使用tmr.ALARM_AUTO 调用计时器,以便它一次又一次地重复。这意味着在您已经设置服务器后将重复计时器,因此尝试再次设置服务器 - 在同一端口上。这会导致使用中的地址错误。

    【讨论】:

    • 我最初使用 HTTP/1.0 200 ok 本身,但是当它不起作用时,比尝试使用 HTTP/1.0 时,因为我对这些东西了解不多。错误所指的地址是我的 WiFi 模块的 IP 地址(作为连接到接入点的站)还是其他地址?正如您在我的代码中看到的那样,我已经在端口 80 上打开了一个到某个服务器的客户端连接,然后我关闭了该服务器。conn:connect(80,"server.co.in")
    • 我什至尝试听其他端口说 9999 但我得到了同样的错误。
    • 错误消息指的是您的 WiFi 模块本地。我建议你先简化你的代码,即只实现一个服务器而不是别的。
    • foo() 和 local_server() 如果单独调用,则工作正常,但如果它们都在单个 lua 脚本中调用,则会发生此错误,可能是因为它已经在端口 80 上侦听本地 http 服务器如果我尝试在同一端口上建立连接,则会出现 PANIC 错误。但我不知道如何纠正它。
    • @aditgupta100:查看更新的答案:根据我对您代码的理解,您正在多次设置服务器,因为您使用了重复计时器。
    猜你喜欢
    • 2021-09-06
    • 2014-12-30
    • 2012-08-14
    • 1970-01-01
    • 2017-05-29
    • 1970-01-01
    • 2020-08-16
    • 1970-01-01
    • 2014-10-14
    相关资源
    最近更新 更多