1.1 Networking
Felix provides builtin support for asynchronous socket I/O. This is supported
by platform dependent event notification services, using the
best of select
, poll
, epoll
, kqueue
, Solaris I/O completion ports and
Windows I/O completion ports. A single pre-emptive thread monitors
the events and does all data transfers on behalf of the client
fibres. The client fibres block, but the thread running them does not.
The subsystem performing the event management is called demux
and that performing the data transfers and fibre scheduling
is called faio
.
// Get library resources include "std/io/iostream"; include "std/io/socket"; open IOStream; open Socket; open IOStream::TerminalIOByteStream[Socket::socket_t]; // announce the program print "NETWORKING_01: MAINLINE: flx tcp stream test\n"; // make a listening socket for our server var listener: socket_t; var port = 0; // you choose mk_listener(&listener, &port, 1); println$ "NETWORKING_01: MAINLINE 01: Got port: " + port.str; println$ "NETWORKING_01: MAINLINE 02: listener created on socket " + str listener; print "NETWORKING_01: MAINLINE 03: spawning server\n"; spawn_fthread { var s: socket_t; println$ "NETWORKING_01: SERVER 01: listening on socket " + str listener; accept(listener, &s); println$ "NETWORKING_01: SERVER 02: Server accepted connection on socket " + str s; ioclose(listener); // not needed anymore var eof = false; println$ "NETWORKING_01: SERVER 03: Attempting write"; write_string(s, "NETWORKING_01: SERVER to CLIENT: server says hi\n", &eof); // newline important here println$ "NETWORKING_01: SERVER 04: write complete"; var st: string; println$ "NETWORKING_01: SERVER 05: Attempting read"; get_line(s, &st); println$ "NETWORKING_01: SERVER 06: read complete"; println$ "NETWORKING_01: SERVER 07: server got " + st.str; ioclose(s); println$ "NETWORKING_01: SERVER 08: closed socket " + str s; }; print "NETWORKING_01: MAINLINE 04: spawning client\n"; spawn_fthread { var eof = false; var c: socket_t; var err = 0; println$ "NETWORKING_01: CLIENT 01: trying to connected to server"; connect(&c, C_hack::cast[+char]c"127.0.0.1", port, &err); // connect to localhost if err == 0 do println$ "NETWORKING_01: CLIENT 02: connected to server on socket is " + str c; var st: string; println "NETWORKING_01: CLIENT 03: Attempting read"; get_line(c, &st); println$ "NETWORKING_01: CLIENT 04: read complete"; println$ "NETWORKING_01: CLIENT 05: connector got "+ st.str; println$ "NETWORKING_01: CLIENT 06: Attempting write"; write_string(c, "CLIENT to SERVER: thanks\n", &eof); // newline important println$ "NETWORKING_01: CLIENT 07: write complete"; ioclose(c); println$ "NETWORKING_1: CLIENT 08: closed socket " + str c; else println$ "NETWORKING_01: CLIENT ERR: Connect error " + err.str; done }; println$ "NETWORKING_01: MAINLINE 05: waiting for job to complete";