[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Using luasocket to read from the keyboard
- From: Nick Gammon <nick@...>
- Date: Fri, 6 Jun 2008 10:29:47 +1000
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