3

I have a standalone lua script that uses lua sockets to connect to a server via TCP IP. It uses receive call to receive data from that server. It works, however, when I try to stop it with Ctrl+C, one of the two scenarios is happening:

-If there is currently no traffic and receive is waiting, Ctrl+C will have no effect. The program will continue to run, and will have to be terminated by kill.

-If there is traffic, the program will exit with the below printout and with the socket still open and with the server not accepting another connection:

lua: luaSocketTest.lua:15: interrupted!
stack traceback:
[C]: in function 'receive'
luaSocketTest.lua:15: in function 'doWork'
luaSocketTest.lua:22: in main chunk
[C]: ?

I tried using pcall to solve the second scenario, without success. pcall doesn't return, the process still throws the error.

Sample of my program is below:

local socket = require ("socket")
local ip = "localhost"
local port = 5003

function doWork ()
    print ("Starting socket: "..ip..":"..port)
    client = assert(socket.connect(ip, port))
    print ("Socket Accepted")
    client:send("TEST TEST")
    while 1 do
      local byte, err = client:receive (1)
      if not err then
         print (byte)
      end
    end
end
while 1 do
  local status = pcall(doWork())
  print ("EXITED PCALL WITH STATUS: "..tostring(status))
  if not status then client:close() end
end
Kara
  • 6,115
  • 16
  • 50
  • 57
elanamig
  • 359
  • 3
  • 6
  • 14

1 Answers1

2

This would be quite a change, but you could employ lua-ev. It allows to add Signal handlers, which is exactly what is required to react to ctrl-c.

local socket = require'socket'
-- make connect and send in blocking mode
local client = socket.connect(ip,port)
client:send('TEST TEST')

-- make client non-blocking
client:settimeout(0)
ev.IO.new(function()
  repeat
    local data,err,part = client:receive(10000) 
    print('received',data or part)
  until err
end,client:getfd(),ev.READ):start(ev.Loop.default)

local ev = require'ev'
local SIGINT = 2

ev.Signal.new(function()
  print('SIGINT received')
end,SIGINT):start(ev.Loop.default)

ev.Loop.default:loop()
lipp
  • 5,586
  • 1
  • 21
  • 32