Left here for archival purposes.

User avatar
By knack
#46509 Hello. I have a TCP/http server with memory leaks, every page request eat memory until the crash "not enough memory"

i try with a simple example i still have that memory leaks.
bug? missed something?

I build the firmware with online tool (dev branch) two days ago.

Code: Select allsrv = net.createServer(net.TCP)
srv:listen(80, function(c)
  c:on("receive", function(sck, pl)
    local resp = {}

    if (string.find(pl, "GET / HTTP/1.1") ~= nil
      or string.find(pl, "GET /index.") ~= nil)
    then
        resp[#resp + 1] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\nServer: NodeMCU\r\nConnection: close\r\n\r\n"
    elseif (string.find(pl, "GET /favicon.ico HTTP/1.1") ~= nil) then
        resp[#resp + 1] = "HTTP/1.1 404 Not Found\r\nContent-type: text/html\r\nServer: NodeMCU\r\nConnection: close\r\n\r\n"
    else
        resp[#resp + 1] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\nServer: NodeMCU\r\nConnection: close\r\n\r\n"
    end

    local function send()
      if #resp > 0
        then sck:send(table.remove(resp, 1))     
      else
        sck:close()
      end
    end
   
    sck:on("sent", send)
    send()
  end)
 
end)
User avatar
By Dsbaha
#46595
knack wrote:Hello. I have a TCP/http server with memory leaks, every page request eat memory until the crash "not enough memory"

i try with a simple example i still have that memory leaks.
bug? missed something?

I build the firmware with online tool (dev branch) two days ago.

Code: Select allsrv = net.createServer(net.TCP)
srv:listen(80, function(c)
  c:on("receive", function(sck, pl)
    local resp = {}

    if (string.find(pl, "GET / HTTP/1.1") ~= nil
      or string.find(pl, "GET /index.") ~= nil)
    then
        resp[#resp + 1] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\nServer: NodeMCU\r\nConnection: close\r\n\r\n"
    elseif (string.find(pl, "GET /favicon.ico HTTP/1.1") ~= nil) then
        resp[#resp + 1] = "HTTP/1.1 404 Not Found\r\nContent-type: text/html\r\nServer: NodeMCU\r\nConnection: close\r\n\r\n"
    else
        resp[#resp + 1] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\nServer: NodeMCU\r\nConnection: close\r\n\r\n"
    end

    local function send()
      if #resp > 0
        then sck:send(table.remove(resp, 1))     
      else
        sck:close()
      end
    end
   
    sck:on("sent", send)
    send()
  end)
 
end)


I concur, I believe I'm seeing a memory leak w/ TCP Server as well. Just the following causes the leak;

Code: Select allsrv = net.createServer(net.TCP)
srv:listen(80, function(conn)
  conn:on("receive", function(conn, payload)

  conn:send("HTTP/1.1 200 OK\r\nServer: nodemcu-httpserver\r\nContent-Type: text/xml\r\nCache-Control: 86400\r\nConnection: close\r\n\r\n")
  conn:on("sent", function(conn) print(node.heap()) conn:close() end)

  end)
end)
User avatar
By marcelstoer
#49587 The cause are closed upvalues. The "sent" callback function receives its own reference of net.socket as a parameter. You have to make sure that you use this one rather than the one received in the "listen" or "receive" callback. Replace
Code: Select allconn:on("sent", function(conn) print(node.heap()) conn:close() end)

with
Code: Select allconn:on("sent", function(sck) print(node.heap()) sck:close() end)

Look at the simple example in https://github.com/nodemcu/nodemcu-firm ... ming-model or the more elaborate one at http://nodemcu.readthedocs.io/en/dev/en ... socketsend. Unfortunately, a number of prominent resources still have the wrong example (README in master branch, Wikipedia, nodemcu.com).