PANIC:调用Lua API时出现无保护错误(wificonfig.lua:33:正在使用的地址)

时间:2017-05-06 11:16:26

标签: lua esp8266 httpserver nodemcu panic

我正在尝试使用由frightanic.com提供的NodeMCU自定义构建来创建一个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

1 个答案:

答案 0 :(得分:0)

        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调用计时器,以便它会一次又一次地重复。这意味着在您已经设置服务器之后将重复计时器,从而尝试再次设置服务器 - 在同一端口上。这会导致使用中的地址错误。