|COGENT Version 2.2 Help|
The Socket box, which is only available in the registered version of COGENT, is a TCP/IP interface for COGENT. It can function as a client, as a server, or both, and supports multiple incoming and outgoing connections at the same time. It allows multiple models to be run simultaneously (but asynchronously) on the same or different machines, communicating with each other via Socket boxes, and it allows COGENT models to interact with networked resources (such as web servers and Telnet clients).
If a Socket box is configured as a server, a suitable port number must be supplied: this is the port on which this box will listen for client connection requests. It will start listening when the box is initialised, and will check for new connections every cycle; it will accept all incoming connection requests, setting up an open connection for each. This will continue until the box is stopped or reinitialised, when it will be shutdown and all current connections will be closed. Re-initialisation, of course, implies that the box will start listening again immediately afterwards.
To use a Socket box as a client, that is, to connect to some other server, socket boxes accept a special trigger, open(Host : Port), where Host is an atom specifying a hostname (e.g., 'cogent.psyc.bbk.ac.uk' or localhost) or an IP address (e.g., '127.0.0.1'), and Port is a positive integer specifying a port on which a suitable server is listening. Even if the box is already listening as a server, it can still initiate one or more client connections too.
Other than special triggers, all messages sent to a Socket box along a send arrow will be transmitted along all open connections from or to that box. Similarly, any messages incoming through open connections will be transmitted along all send arrows leading from the Socket box. This is the whole point.
A model containing one or more Socket boxes will continue running if any connections from or to a box in the model are still open, or if a server box is listening for connections.
Sending a Socket box a close message will close all open connections from or to that box, but it will not shut down the server, if one is running. Sending the box a stop message will close all open connections to or from the box, like the close message, and moreover, it will shut down any server in that box. This allows the usual default conditions to govern whether the whole model halts naturally or continues running.
It should be noted that unlike COGENT models in general, model runs using Socket boxes cannot be halted and restarted in a later OOS session. This is because ending the OOS session will close any open connections, so clients will not still be connected when the model is restarted. Initialisation is usually required.
Socket boxes support two data formats to transmit and receive data: raw mode sends and receives lists of ASCII values, corresponding to lines of textual output and input, whereas the default mode sends and receives Prolog terms. Raw mode is useful to allow COGENT models to interact with arbitrary networked systems, such as web servers, or with Telnet clients for user interaction. The default mode, by contrast, simply sends and receives Prolog terms, which is more appropriate for direct communication between COGENT models.
Raw mode: If the box is configured to use raw mode, messages
corresponding to lines of output must be specified as
raw(LineString) where LineString is a Prolog string,
or a list of ASCII values, for example raw("hello") or
raw([104, 101, 108, 108, 111]). These
strings are each formatted on the output stream with a following
newline (ASCII 10).
Similarly, lines of input from connections, terminated with newlines, are converted to raw(LineString) format before being passed along send arrows to other boxes. The newline character is not included in the parsed string, and any carriage returns (ASCII 13) in the input are ignored.
Default mode: In the default mode, any Prolog term sent to a Socket box (except special triggers) will be sent on along any open connections to the peers, which must also be in default mode to ensure success.
Initialise (possible values: Each Trial/Each Block/Each Subject/Each Experiment/Each Session;
default: Each Trial)
This property determines the timing of socket initialisation. In the case of sockets acting as servers, this determines when the server is started.
Server (Boolean; Default FALSE)
If checked, a server will be started on the Port specified in Port when the box is next initialised. The server will accept connection requests from any clients which issue them. A model containing a box with the Server property checked will not stop before the box itself is stopped.
Port (positive integer; Default 15000)
This is used to specify the port number on which the server will listen, if Server is enabled.
Raw IO (Boolean)
This is used to specify whether information is transmitted and received as lists of ASCII values (when enabled), or as Prolog terms (when disabled). This will affect all connections to or from the box.
open(Host : Port)
Opens a connection to the server on Host:Port. Host must be an atom, either a text hostname (e.g., 'cogent.psyc.bbk.ac.uk' or localhost) or an IP address (e.g., '127.0.0.1'), and Port should be a suitable positive integer. While an open connection exists, the model will not stop executing.
If a Socket box receives a close message, all open connections to or from that box will be closed, and the model may be able to stop executing. The box itself is not stopped, however, and this will not shutdown an active server.
Like the stop message generally, it causes the recipient box to cease all operations until the box is next initialised. In the case of Socket boxes, there are two extra side effects: first, all open connections with other boxes, whether in client or server mode, are closed (as for the close trigger); second, and crucially, if a server is active in this box, it is also shut down.
If the box is configured for Raw IO any messages sent to it must be in this format, and the LineString will be written to the outgoing stream. In Raw IO mode, all incoming data is also parsed into lines, and passed along send arrows as raw(LineString) terms. This allows the box to interface with arbitrary network processes, such as web servers.
To hit a web server and collect its output, first of all your Socket box must be configured for Raw I/O. Now, using a process, open a connection to the server (usually on port 80), then send it a HTTP GET request, followed by a blank line, like this:
SEND open('www.myhost.com' : 80) to IO SEND raw("GET / HTTP/1.0") to IO SEND raw("") to IO
If all is well, the web server will reply with a stream of output, corresponding in this case to its root document, in the form of raw(...) messages representing individual lines. The output lines can be collected in order, by using an unrefracted, triggered rule to add the messages to a FIFO buffer with Duplicates enabled. The lines can then be read, in order, and at your leisure, from the buffer. In this example, there is no need to explicitly close the connection, as it will be closed in due course by the server.
By the way, to make this example more useful, you can replace the first "/" in the GET command with the path to some other page on that server, e.g., "GET /path/to/mypage.html HTTP/1.0". Also, you will notice that a few lines at the beginning of the web server's output are headers, and these are separated from the usual HTML content by a blank line. But this is not the place to teach HTTP...
There is an apparent need for a means to close down individual connections, without closing them all; this depends on finding a good way to refer to individual connections, for the benefit of other COGENT boxes.
Similarly, a model might want to send a message to one or some peers, but not all. Again, it depends on the same putative reference mechanism.
A match routine?
Maybe the open connections should be maintained by each box as a matchable pseudo-state, containing info about the Hostname but also the Socket ID for unique reference. This can provide the reference facilities needed by the individual close and individual message functions described above.
Windows 9x client mode
The client side on MS windows 95 and 98 gets stuck when attempting to make a connection. This only happens the first time a connection is attempted during an OOS session, and it can be unstuck by either typing into the OOS console (if enabled), or by selecting "End task" for the OOS process in the Task manager window (Accessible by CTRL-ALT-DEL on a windows 95/98 machine). This will attempt to kill the OOS process, but will not succeed, and a side effect is to unstick the connection. After a few moments a dialog box will appear, saying the program is not responding: make sure you click Cancel here. The bug seems to be due to an incompatibility between SWI Prolog and the windows 95/98 winsock.dll; it does not affect the UNIX version, and may well not affect NT-derived windows platforms.
Raw mode and binary data
Raw mode should be adequate for text data, but it will mangle incoming binary data, since it currently ignores CR characters and splits the stream into lines terminated by LF characters. This could presumably be fixed somehow, if anybody cares.
|COGENT Version 2.2 Help|