util.Channels.select
Waits for activity on a set of TCP socket listening
base.Channel
objects.
Syntax
util.Channels.select(
channels DYNAMIC ARRAY OF base.Channel
)
RETURNS INTEGER
- channels is an array of
base.Channel
objects opened withbase.Channel.openServerSocket()
or provided byutil.Channels.accept()
. - Returns the index of the channel that can be used to read data from.
Usage
The util.Channels.select()
takes an array of base.Channel
objects, all opened as TCP
socket readers with base.Channel.openServerSocket()
.
If one of the listening channels has some data available to read, the select()
method returns the index of that channel in the array passed as parameter.
If the returned index matches the index of the initial server channel passed in the first call to
select()
, use the util.Channels.accept()
method to get a new base.Channel
object to read from that port. The new base.Channel
object must be added to the set
of channels passed to select()
, and can then be used to read data from it with
base.Channel.readLine()
.
Example
The server.4gl file:
IMPORT util
FUNCTION main()
DEFINE x, n INTEGER
DEFINE channels DYNAMIC ARRAY OF base.Channel
DEFINE s base.Channel
DEFINE c base.Channel
DEFINE buf STRING
LET s = base.Channel.create()
CALL s.openServerSocket("127.0.0.1", 4711, "u")
LET channels[1] = s
DISPLAY "server: listening on port 4711"
WHILE (x := util.Channels.select(channels)) > 0
DISPLAY SFMT("server: select() returned index: %1",x)
IF x == 1 THEN
LET c = util.Channels.accept(s)
LET n = channels.getLength() + 1
LET channels[n] = c
DISPLAY SFMT("server: accept() returned new channel: %1", n)
ELSE
LET c = channels[x]
LET buf = c.readLine()
IF c.isEof() THEN
DISPLAY SFMT("server: close(%1)", x)
CALL c.close()
CALL channels.deleteElement(x)
ELSE
DISPLAY SFMT("server: read(%1): %2", x, buf)
CALL c.writeLine(buf)
CALL c.flush()
END IF
END IF
END WHILE
END FUNCTION
MAIN
DEFINE x, n INTEGER
DEFINE c base.Channel
DEFINE pid INTEGER
DEFINE buf STRING
LET n = NVL(arg_val(1), 20)
LET pid = fgl_getpid()
LET c = base.Channel.create()
DISPLAY SFMT("client pid:%1 start", pid)
CALL c.openClientSocket("127.0.0.1", 4711, "u", 10)
FOR x = 1 TO n
LET buf = SFMT("pid=%1 msgnum:%2", pid, x)
DISPLAY SFMT("client pid:%1 write:'%2'", pid, buf)
CALL c.writeLine(buf)
LET buf = c.readLine()
DISPLAY SFMT("client pid:%1 read :'%2'", pid, buf)
SLEEP 1
END FOR
DISPLAY SFMT("client pid:%1 stop", pid)
END MAIN
Compile both programs, start server in one dedicated terminal, then start several client instances and watch the outputs.