Prev: Module comm: Serial Communications
Module net: TCP/IP Networking
This module supports creation of active TCP connections to hosts anywhere on the Internet. Secure connections based on SSL or TLS are also supported, as well as simple host name and IP address resolution.
Listening for incoming (passive) connections is also possible. Keep in mind that this generally only makes sense for local connections to 127.0.0.1, as the phone is usually part of a private network and not visible to the rest of the internet.
This module does not support IPv6.
Connections Are Streams
Once created, a TCP/IP connection, whether secure or unsecure, is accessed via module
io:
- io.read, io.readln, and io.readm receive data,
- io.write, io.writeln, io.writem, io.print, and io.println send data,
- io.avail gets the number of bytes which can be read without blocking,
- io.wait waits for data which can be read without blocking, or for an incoming connection,
- io.close closes the connection or listening socket.
- io.ces gets and sets the character encoding scheme. As with files, the default is io.raw.
- io.timeout sets the timeout for send, receive and wait operations.
- io.flush sets the auto flush state. If auto flushing is disabled, io.flush must be called to make sure all data is sent.
Internet Access Points
Except for local connections, using TCP/IP requires the phone to connect to an IAP (Internet Access Point), typically via GPRS or UMTS, or via WLAN on devices supporting it. The TCP/IP functions of the phone deal with these automatically, depending on the phone configuration. The
net module provides limited support to manage IAP connections: see
net.iap,
net.iaps,
net.start and
net.stop.
net.accept
• function accept(pstream) → Native Object
Permissions: CostComm
Waits for a new incoming connection on the port defined by pstream, and returns it as a stream.
pstream is a passive stream which is obtained by call to net.listen. See there for a complete example.
net.adr
• function adr(hostname) → Array
Permissions: CostComm
Resolves a host name to its IP address or addresses. The addresses are returned as an array of strings, each string representing the IP address in the standard dot notation.
print net.adr('www.google.com')
→ [216.239.59.103,216.239.59.104,
216.239.59.99,216.239.59.147]
|
See also: net.local, net.remote
net.cert
• function cert(stream) → Array
Permissions: CostComm
Gets the X.509 server certificate of the secure connection stream. The certificate identifies and (if it is valid) authenticates the host the connection has been made to.
This function returns null if stream is not secure.
The certificate is returned as an array with the following keys:
| Key | Meaning | Type |
| subject | Certified subject (in X.500 format) | Array |
| issuer | Certificate issuer (in X.500 format) | Array |
| version | Certificate version | Number |
| serial | Certificate serial number | String |
| start | Start of validity period | Seconds |
| end | End of validity period | Seconds |
| md5 | Fingerprint of certificate (MD5 hash) | String |
| |
subject and issuer are arrays containing key-value pairs, with the keys being hierarchical OID numbers. For instance, the key "2.5.4.3" stands for "Common Name", and "2.5.4.10" for "Organization Name".
start and end define the validity period of the certificate, in seconds since year zero, as used by module time.
serial and md5 encode each byte as a string character; use .code to convert them to single bytes.
// connect to a secure Web server
s=net.conn("www.yellownet.ch", 443, net.ssl);
// send a request
io.write(s, 'GET / HTTP 1.1\r\n\r\n');
// read the first four lines
for i=1 to 4 do
print io.readln(s)
end
→ HTTP/1.1 302 Found
Date: Tue, 24 May 2005 12:47:08 GMT
Server: Stronghold
Location: https://www.postfinance.ch/
// look at the certificate
c=net.cert(s);
print c["subject"]["2.5.4.3"]
→ www.yellownet.ch
print c["subject"]["2.5.4.10"]
→ Die Schweizerische Post
// close the connection
io.close(s)
|
net.conn
• function conn(host, port, secure=null, silent=false, authName=null) → Native Object
Permissions: CostComm
Connects to the host host on TCP/IP port port. host can be a host name (e.g. "www.m-shell.net"), or an IP address (e.g. "212.117.205.10").
If secure=null, the connection is unsecure. To secure the connection, use one of the following constants:
• const ssl = "SSL3.0"
Use SSL (Secure Sockets Layer) 3.0.
• const tls = "TLS1.0"
Use TLS (Transport Layer Security) 1.0.
If silent=false, the user will be prompted when the certificate presented by the server cannot be authenticated or has expired, giving the user the opportunity to accept the certificate for this session.
If silent=true, an invalid certificate will simply throw ErrCertificateUnknown, or some other SSL exception.
authName indicates the expected name authenticated by the certificate. If authName=null, it defaults to host.
| | |
| Compatibility of Secure Connections |
| Sony Ericsson phones | Unreliable, may hang |
|
// connect to airbit's SMTP mail server
s=net.conn("mail.airbit.ch", 25);
// read the prompt
print io.readln(s)
→ 220 mail.airbit.ch ESMTP ...
// immediately logout again
io.write(s, "QUIT\r\n");
// read the goodbye message
print io.readln(s)
→ 221 Service closing transmission channel
// close the connection
io.close(s)
|
For a secure connection example, see net.cert.
net.iap
• function iap() → Array
Permissions: CostComm
• function iap(setting) → Array
Permissions: CostComm+WriteApp
Capabilities: extended
Sets and gets the preferred Internet Access Point (IAP) to use. The preferred IAP setting consists of an array with three elements:
| Index | Meaning | Type |
| 0 | Prompt user for IAP when connecting | Boolean |
| 1 | Preferred IAP id | Number |
| 2 | Bearer types supported by this setting | Number |
| |
The preferred IAP id corresponds to an id of the IAP table in the phone, as returned by net.iaps. The bearer set defines the set of bearer types supported by this setting.
Without arguments, this function returns the current preferred IAP setting. With a single boolean argument, it returns the old setting and sets the "prompt user" flag. With an array argument, it updates the corresponding entries, depending on the length of the array (1 to 3 elements).
// get current setting
s=net.iap();
print s
→ [false,14,3]
// change the preferred IAP id to 2 and enable prompting
net.iap([true, 2])
// disable prompting
net.iap(false)
// restore the old setting
net.iap(s)
|
net.iaps
• function iaps(bearerMask=net.csd|net.wcdma|net.lan| net.cdma2000|net.virtual) → Array
Permissions: CostComm
Returns the configured IAPs whose bearer matches one of the flags in bearerMask. The mask bits are the following:
• const csd = 1
circuit switched data: slow dialup connection.
• const wcdma = 2
wide band code division multiple access, a 3G (UMTS) technology; also includes GPRS if 3G is not available.
• const lan = 4
local area network, typically WLAN.
• const cdma2000 = 8
code division multiple access 2000, another 3G technology.
• const virtual = 16
virtual bearer using another transport.
Each array element returned is itself an array with the following fields:
| Key | Meaning | Type |
| id | Internal IAP id | Number |
| name | IAP name | String |
| |
// get all IAPs
for p in net.iaps() do
print p
end
→ [1,Easy WLAN]
[2,Swisscom GPRS]
[3,Swisscom MMS]
[4,Swisscom Internet]
[5,Airbit WLAN]
// get only local network (WLAN) IAPs
for p in net.iaps(net.lan) do
print p
end
→ [1,Easy WLAN]
[5,Airbit WLAN]
// use the last WLAN for further connections
net.iap([false,p['id']])
|
net.listen
• function listen(port, addr='0.0.0.0', queue=4) → Native Object
Creates a passive stream listening for incoming connections on the given port and address, and returns it. The address 0.0.0.0 allows connections to any valid IP address of the device. queue is the maximum number of queued unaccepted connections.
The passive stream can be passed to the following functions:
- net.accept waits for an incoming connection, and returns it.
- io.wait allows to simultaneously wait for an incoming connection and data being available on established connections or streams. If io.wait returns a passive stream, io.avail on this stream will return 1 afterwards.
- io.close closes the passive stream and stops listening on the given port, freeing it for other processes.
The following example is a server waiting for connections on port 4242, receiving lines from the incoming connections and sending them back reversed. You may want to compare this example to the corresponding Bluetooth implementation in section
* (). The main difference is that TCP/IP supports multiple connections per port and thus requires
io.wait to manage them simultaneously.
use net, io, array
// create a passive stream listening on port 4242
p=net.listen(4242);
m=[p]; // the monitored streams
while true do // loop forever
// wait for a client
io.print(io.stdout, "Waiting...");
s=io.wait(m);
if s=p then // new connection, accept it
print "got new connection.";
append(m, net.accept(p))
else // data on existing connection
io.print(io.stdout, "reading...");
line=io.readln(s);
if line#null then
print "got", line;
io.writeln(s, reverse(line))
else // EOF, remove connection
print "lost connection.";
io.close(s);
array.remove(m, array.index(m, s))
end
end
end
→ Waiting...got new connection.
Waiting...got new connection.
Waiting...reading...got Lucky Luke
Waiting...reading...got Jolly Jumper
Waiting...reading...lost connection.
Waiting...
|
Sample client calls producing the above output are:
s1=net.conn('127.0.0.1', 4242);
s2=net.conn('127.0.0.1', 4242);
io.write(s1, 'Lucky Luke\n');
io.readln(s1)
→ ekuL ykcuL
io.write(s2, 'Jolly Jumper\n');
io.readln(s2)
→ repmuJ ylloJ
io.close(s1)
|
net.local
• function local(stream) → Array
Permissions: CostComm
Returns the local (your own) IP address and port of the connection defined by stream as an array:
| Key | Meaning | Type |
| adr | TCP/IP address | String |
| port | TCP/IP port | Number |
| |
Throws ErrBadHandle if stream is not an open connection.
s=net.conn('www.post.ch', 80);
print net.local(s)
→ [10.122.18.7,32803]
|
net.name
• function name(address) → Array
Permissions: CostComm
• function name() → Array
Permissions: CostComm
Finds the host names belonging to an IP address. The IP address must be a string in standard dot notation. The names are returned as an array of strings.
Without arguments, returns the local (own) host name.
print net.name('62.65.129.6')
→ [mail.infowing.ch]
print net.name()
→ [localhost]
|
net.remote
• function remote(stream) → Array
Permissions: CostComm
Returns the remote (the remote host's) IP address and port of the connection defined by stream as an array:
| Key | Meaning | Type |
| adr | TCP/IP address | String |
| port | TCP/IP port | Number |
| |
Throws ErrBadHandle if stream is not an open connection.
p=net.listen(4242);
s=net.accept(p);
print net.remote(s)
→ [127.0.0.1,39934]
|
net.shut
• function shut(stream, abort=false) → null
Permissions: CostComm
Shuts the connection defined by stream down. If abort=false, shutdown is gracefully, i.e. all pending data is transmitted. If abort=true, sending and receiving is stopped immediately.
io.close also shuts down a connection, but net.shut gives finer control over connection termination, and allows to catch errors.
s=net.conn('mail.airbit.ch', 25);
// abort the connection
net.shut(s, true)
|
net.start
• function start() → null
Permissions: CostComm
• function start(prompt) → null
Permissions: CostComm
Starts the IAP connection.
Without argument, connects using the current IAP settings. This is normally not required, as connections are created on demand.
With argument, connects using the current IAP settings, but overrides the prompt flag: if prompt=false, the user is not prompted to choose an IAP; if prompt=true, the user is always prompted.
// start the connection without prompting for an IAP
net.start(false)
|
net.stop
• function stop() → null
Permissions: CostComm
Capabilities: certified
Stops the current IAP connection. Calling this function is normally not required, as connections are removed when they are no longer needed.
// change the IAP, then stop the connection
net.iap([false, 7]);
net.stop()
// resolving a host name should restart the connection
// with the new IAP
net.adr('www.m-shell.net')
→ [62.202.44.142]
|
net.timeout
• function timeout() → Number
Permissions: CostComm
• function timeout(ms) → Number
Permissions: CostComm
Gets or sets the timeout used when looking up names and when connecting. Without arguments, returns the current timeout in milliseconds. With one argument, returns the old timeout, and sets the new timeout to ms. Setting the timeout to zero (the default) or a negative value disables timeouts, i.e. TCP/IP operations can block indefinitely, or use a timeout defined by the underlying system.
Throws ExcValueOutOfRange if ms exceeds 2147483 (35 minutes and 47.483 seconds).
The timeout is used in all following name resolution, connect and shutdown calls: whenever an operation does not complete within the given number of milliseconds, it throws ErrTimedOut.
// give the phone 10 seconds to connect
net.timeout(10000);
try
s=net.conn("mail.airbit.ch", 25)
// connection successful...
catch e by
if index(e, "ErrTimedOut") # 0 then throw e end;
print "Could not connect within 10 seconds"
end
|
Next: Messaging© 2004-2011 airbit AG, CH-8008 Zürich
Document AB-M-LIB-888