![]() |
IPv4 Sockets support for the Lua language |
home · download · what is · introduction · functions · modules · index
Below is a little introduction on how to get the library up and running with your applications and a little introduction on network programming with LuaSocket.
To have the library functions made available to a Lua script, the interpreter running the script must be linked to the luasocket library, and to whatever libraries the OS in use requires for socket programming. The functions are registered in the Lua state given as the parameter to the function lua_socketlibopen, the only C function exported by the library. The scripts can then use all registered functions.
The network support in the Lua language could closely mirror the C API or could implement a new, independent, transport layer abstraction. Having an API similar to the C API would make things easier for those who are used to socket programming. On the other hand, the simplicity of the Lua language would be lost. We ended up with something in between, in the sense that function names and semantics have been copied from the C API whenever possible, whereas their usage in Lua has been greatly simplified.
One of the major differences in the created API is the timeout control provided by the library. All I/O operations are blocking by default. In other words, the send, receive and accept functions will block the caller application until the operation is completed (if ever). The application can, however, specify upper limits on the time it can be blocked by LuaSocket ("return" timeout), on the time LuaSocket can be blocked by the OS ("blocked" timeout) or a combination of the two. Remember that each LuaSocket call performs several OS calls, so that the two timeout values are not equivalent.
Another major difference is the receive pattern capability. Applications can read data from a TCP client socket line by line, chunk by chunk, until the connection is closed etc. All I/O reads are buffered and the performance difference between different receive patterns is negligible.
Finally, host name resolution is transparent, meaning that most functions accept both IP addresses and host names. In case a host name is given, the library queries the system's resolver and tries all returned IP addresses until one succeeds or all fail. IP addresses are directly encoded and are therefore more efficient. The toip and tohostname functions are provided to convert between host names and IP addresses.
Socket objects are represented as tables in the Lua language. Different socket types accept different operations. These operations are available both as stand-alone global functions and as table methods of the socket objects (i.e. the calls send(sock, "test") and sock:send("test") are equivalent). It is considered better style to use the table method versions, which are also slightly more efficient.
TCP (Transfer Control Protocol) is reliable stream protocol. In other words, applications communicating through TCP can send and receive data as an error free stream of bytes. Data is split in one end and reassembled transparently on the other end. There are no boundaries in the data transfers. The library allows users to read data from the sockets in several different granularity: patterns are available for words, lines, arbitrary sized blocks or "read up to connection closed", all with similar performance.
The library distinguishes two types of TCP sockets: client sockets and server sockets.
Client sockets are used to exchange data between two applications over the Internet. Client sockets are created by the connect global function or returned by the accept server socket method. Applications can call the methods send and receive to send and receive data. The other methods available for client socket objects are getsockname, getpeername, timeout and close.
Server sockets are created by the bind global function and are associated with a address and port on the local host. Applications use the accept server socket method to wait for a client connection on a server socket. Once a connection is established, a client socket object is returned representing this connection. The other methods available for server socket objects are getsockname, timeout and close.
Example:
A simple echo server, using LuaSocket. The program binds to an ephemeral port (one that is chosen by the operating system) on the local host and awaits client connections on that port. When a connection is established, the program reads a line from the remote end and sends it back, closing the connection immediately after. You can test it using the telnet program.UDP
server, err = bind("*", 0) assert(server, err) ip, port = server:getsockname() write("Please telnet to localhost on port " .. port) while 1 do client, err = server:accept() client:timeout(10) line, err = client:receive() if not err then client:send(line .. "\n") end client:close() end
UDP (User Datagram Protocol) is a non-reliable datagram protocol. In other words, applications communication through UDP send and receive data as independent blocks, which are not guaranteed to reach the other end. Even when they reach the other end, they are not guaranteed to be error free. Data transfers are atomic, one datagram at a time. Reading only part of a datagram discards the rest, so that the next read operation will act on the next datagram. The advantages are in simplicity (no connection setup) and performance (no error checking or error correction).
An UDP socket object is created by the udpcreate function. UDP sockets do not need to be connected before use. The method sendto can be used immediately after creation to send a datagram to any UDP (ip, port) pair. Host names are not allowed for performance reasons. Methods receive and receivefrom can be used to retrieve datagrams, the latter returning the ip and port of the sender as extra return values (thus being slightly less efficient).
When communication is performed repeatedly with a single peer, an application should call the setpeername method to specify a permanent partner. The method send can then be used to send data directly to the peer, and methods receive and receivefrom will only return datagrams originating from that peer. There is about 30% performance gain due to this practice.
To associate an UDP socket with a local address, an application calls the setsockname function. Otherwise, the socket is automatically bound to an ephemeral address before the first data transmission. The other methods available for UDP sockets are getpeername, getsockname, timeout and close.
Example:
A simple daytime client, using LuaSocket. The program connects to a remote server and tries to retrieve the daytime, printing the answer it got or an error message.DNS
host = "localhost" -- change here to your remote hostname or ip address port = port or 13 ip, err = toip(host) assert(ip, err) udp = udpsocket() err = udp:sendto("anything", ip, port) assert(not err, err) dgram, err = udp:receive() assert(dgram, err) write(dgram)
DNS (Domain Name System) is the system that maps host names (such as 'www.lua.org') into their associated IP addresses (such as '200.255.249.234'). Domain names were created because humans find it easier to memorize words than numbers. Translation between names and numbers is performed by an external service and is not part of the TCP or UDP protocols.
UDP and TCP are only concerned with IP addresses --- they do not understand domain names. One of the advantages of the LuaSocket library is that in most of the cases it automatically performs domain name lookup when needed. However, since these translations have a cost, the library provides two functions, toip and tohostname to perform explicit DNS translations in both ways.
home · download · what is · introduction · functions · modules · index
![]() | and | ![]() |
Last modified by Diego Nehab on Thu Sep 27 16:18:27 EST 2001 |