lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hello all,

I am trying to write a Lua application that reads, asynchronously, from both a TCP/IP connection, and the keyboard, much like telnet does. Specifically, I want to pause on the "select" statement and await either data from the host, or something typed by the user. However I am having trouble getting it to work.

A small application written in C works, as you can supply standard file descriptors, something like this:

    FD_ZERO( &in_set  );
    // add our socket
    FD_SET( s, &in_set  );
    // and stdin
    FD_SET( STDIN_FILENO, &in_set  );
if (select (UMAX (s, STDIN_FILENO) + 1, &in_set, NULL, NULL, &timeout) == 0)
      return 0;


However my attempts to emulate this behaviour in luasocket have been unsuccessful.

The closest I get is this:

-----------
require 'socket'

-- TCP connection to server
conn = assert (socket.connect("localhost", 4000))

-- keyboard input 'socket'
keyboard = socket.tcp ()
keyboard:close ()
keyboard:setfd (0) -- I Googled setfd for this idea (STDIN is descriptor 0)

recvt = { conn, keyboard }

while true do

 readable, writable, error = socket.select(recvt, nil , 10)
 print "got past select"

 if readable [conn] then
   s = conn:receive (100)
   io.write (s)
 end -- if

 if readable [keyboard] then
   print "got keyboard input"
--   s = assert (keyboard:receive (100))
   s = io.read (10)
   io.write (s)
 end -- if

end -- while
---------------

Assuming there is a server to connect to at port 4000, this code successfully displays the welcome message from the server, but ignores any typing on the keyboard.

However if you change the select to only look at the keyboard, namely:

recvt = { keyboard }


Then it will work in a fashion. It detects keyboard input, once you press <enter>, but only returns the first 10 characters each time through the loop. That is, you get 10 characters every 10 seconds. If I make it io.read (100) it returns nothing until 100 characters are typed.

If I change the code from io.read (10) to keyboard:receive (100) I get this error message:

  calling 'receive' on bad self (tcp{client} expected, got userdata)

Somehow I think I am doing this wrongly, and any suggestions from the luasocket experts are welcome. :-)

- Nick