Socket, Process, and Stream Input and Output

SenseTalk provides a set of commands for reading and writing sockets, processes, and the standard input and output streams (i.e., stdin, stdout, stderr). Fundamentally, these forms can all be treated as streams of data. The read and write commands include many options to make it easy to read or write any type of data including numbers in many formats, text, and raw binary data. HTTP and XML-RPC messages are also supported directly to further simplify communication with many servers on the internet.

Although some details differ between the different types of streams, the basic process of working with all of them follows the same sequence: open, read and/or write, close. The main exception to this sequence is that the standard input, standard output, and standard error streams don't require opening or closing because they are considered to be open at all times.

Note: The commands and functions that you use to work with sockets, processes, and stream data are generally similar to the commands and functions you might use for working with files and file system objects. However, for information about working with files and file systems, see File and Folder Interaction.

These are the commands, functions, and global properties used for working with sockets, processes, and streams in your scripts:

The socket input and output commands (open socket, close socket, read from socket, and write … to socket) permit you to open a connection to a socket provided by another process and read and write data through that connection. You cannot seek to a specified location on a socket because a socket is just an open communication channel between two processes.

Similarly, the process input and output commands (open process, close process, read from process, and write … to process) allow you to launch an external process and communicate with it by writing to the standard input and reading from the standard output of that process.

The read and write commands can also be used to read from standard input and to write to the standard output or standard error streams (read from input, write … to output, write … to error).

The openSockets function returns a list of all of the currently open sockets.

The DefaultStringEncoding global property controls the encoding format that is used when reading or writing text from a file or socket.

Open Socket Command

Behavior: The open socket command must be used to open a socket before anything can be read from or written to that socket using the read or write commands. When you are finished with a socket, it should be closed using the close socket command.

Open socket establishes a TCP socket connection to another process (program). The other process may be running on the same computer, or on some other computer on the network. It must already be running, and have registered a socket to which SenseTalk can connect. Once the connection is established, data may be transmitted in either direction in whatever manner both sides understand.

Syntax:

open socket socketIdentifier

The socketIdentifier must be of the form host:port where host is the name or IP address of the machine, and port is the port number on that machine of the socket to be connected to.

The socketIdentifier may optionally end with a pound sign “#” (or a vertical bar “|”) character followed by an arbitrary number or identifier string. This serves the purpose of allowing you to create multiple identifiers to establish more than one connection to the same host and port, and identify each connection uniquely – just use the appropriate socketIdentifier with the read, write, and close commands to identify the correct connection.

If the socket connection cannot be established within the time specified by the readTimeout global property, an exception will be thrown. Use the openSockets function to get a list of all sockets which are currently open.

Example:

open socket remoteListener

Example:

open socket "192.168.1.4:22"

Example:

open socket "localhost:5900#2"

Open Process Command

Behavior: Launches an external process and opens a connection through which the script may interact with that other process. If all that is needed is to run an external process and receive any output from that process when it completes, the shell function provides a much simpler way to achieve that. The open process mechanism, on the other hand, provides much greater flexibility, allowing the script to conduct complex interactions with another process, or to start a lengthy operation without blocking the script and retrieve the results of that operation at a later point in the script.

Open process launches another process (program) which may be (and most commonly is) a shell through which still other programs may be executed. Once the other process is launched, a connection is established and text may be transmitted in either direction – the script may write to the standard input and read from the standard output of the other process.

If the process cannot be launched, the result function will be set to an exception (or the exception will be thrown, if The ThrowExceptionResults global property is set to true). The openProcesses function can be used to get a list of all processes which are currently open.

Syntax:

open process processIdentifier {with options options}

The processIdentifier should be in the form processPath#identifier where processPath is the full path of the process to run. If processPath is omitted, a shell process will be launched (as specified by the shellCommand global property). The #identifier portion is also optional – it merely serves as a way to make a processIdentifier unique, so that a script can open and interact with multiple processes at once that use the same processPath.

If options is used, it should be a property list that may include any of these properties:

parameters

a list of values to be passed as parameters to the process when it is launched

folder or directory

the current directory where the process will be run

environment

a property list specifying environment variables and their values

Example:

open process preferredShell & "#myshell"

Example:

open process "/bin/sh" with options myOptions

Example:

open process "/usr/local/bin/mysql#2"

Close Socket, Close Process, Close All Commands

Behavior: Closes an socket; or process; or all open files, sockets, or processes. The close all sockets command closes all currently open sockets, regardless of which script or handler opened the socket. This behavior could be potentially problematic if sockets have been opened by other scripts, and are still in use. Use the openSockets() function to get a list of all open sockets. The same applies to the close all processes command.

The close socket command closes a socket that was previously opened with the open socket command. The socketIdentifier should be identical to the identifier used when opening the socket.

The close process command closes a process that was previously opened with the open process command. The processIdentifier should be identical to the identifier used when opening the process.

The close all sockets and close all processes commands can be used to close all of the currently open sockets or processes. SenseTalk automatically closes all open sockets and processes whenever it stops executing your scripts, but it is good practice to for your script to close them when it is done working with them.

Syntax:

close socket socketIdentifier

close process processIdentifier

close all sockets

close all processes

Example:

close all processes -- close all open processes

Example:

close socket "localhost:5900"

Example:

close process "#9"

Read from Socket, Read from Process, Read from Input Commands

Behavior: Reads data (text or numbers) from an open socket or an open process, or from the standard input stream.

Use the read from ... command to read data from a socket, process, or standard input. Data is read into the variable it or into a destination container if specified (using an into clause). When there is no more data to read, the destination container will be empty. Any time less data is read than was requested, the result function will contain a value giving the reason (such as time out).

The read command can read a specified number of characters, words, items, lines, or bytes; can read until a specified delimiter is found; or can read a list of one of several different types of numeric values. Reading begins at the current position. The syntax of the read command is flexible, allowing the various options to be specified in any convenient order.

Note: In order to read from a file, see the Read from File Command.

Syntax:

The syntax of the read from ... command is flexible, allowing the various options to be specified in any convenient order.

read Options

Source Options: One Required.

from socket socketIdentifier

from process processIdentifier

from [input | stdin]

Quantity Options: Optional. Only one can be used at a time.

until [{theeof | {theend {of {thefile} | terminator]

for quantity {dataType}

[an | quantitydataType

{for} {anhttp {message request response}

{for} {an} [xmlrpc xml-rpc] {message request response}

Other Options: Optional. More than one can be used at a time.

at startPos

in | [timeout time out] {after in} ] timeoutDuration

into container

One of the three from options is required, to specify the source from which to read. All other options are optional, but only one of each type may be specified. If neither a for nor until option is given, a single byte is read. If into container isn't specified, the value will be read into the special it variable.

Tech Talk

You do not need to open the standard input stream – it is always open (you can refer to it as stdin instead of input if you prefer).

When reading from a socket, the socketIdentifier expression must yield the exact identifier used when a socket was previously opened with the open socket command.

When reading from a process, the processIdentifier expression must yield the exact identifier used when a process was previously opened with the open process command. The value that is read corresponds to the standard output from the process.

If into container is specified, the data that is read is put into the given container. If an into option is not specified, the data is read into the special it variable.

If until terminator is specified, all of the characters from the starting position until the next occurrence of the specified character or string will be read. This is useful for reading one line at a time from the source (by using return as the terminating character), or to read just until some other delimiting character (such as a tab). The terminator can be more than one character in length, and will be returned as part of the value that was read. Specifying until eof or until end will read all the way to the end of the file, or to the end of input from a socket or stream. The standard input stream indicates it is at the end after a Control-D character is received. For sockets and processes, the until eof or until end option will wait until either some input is available, or the duration of the readTimeout or in timeLimit (see below) has elapsed. This greatly simplifies reading when some input is expected.

If for quantitydataType is used, the number of characters or other data elements specified by quantity are read from the file. If dataType is a text chunk type (characters, words, items, or lines), text is read until the requested amount is available. The final delimiter (if any) is not included with the text that is read. If no dataType is given, bytes are assumed (and the word for is required in this case).

The in timeoutDuration option gives the maximum time the read command will wait for the requested data to become available. If a time is not specified, the value of the readTimeout global property will be used instead. If the requested data is not read within the time specified by timeLimit or readTimeout, whatever has been read will be returned and the result function will be set to indicate time out.

If you specify a numeric dataType instead of a text chunk type, the value stored into it or container by the read will be a list of the data values that were read. The following numeric data types may be used:

DataType

Value

int1 or 8-bit integer

an 8-bit (or 1 byte) signed integer

uint1 or unsigned 8-bit integer

an 8-bit (or 1 byte) unsigned integer

int2 or 16-bit integer or short integer

a 16-bit (or 2 byte) signed integer

uint2 or unsigned 16-bit integer

a 16-bit (or 2 byte) unsigned integer

int4 or 32-bit integer or integer

a 32-bit (or 4 byte) signed integer

uint4 or unsigned 32-bit integer

a 32-bit (or 4 byte) unsigned integer

int8 or 64-bit integer

a 64-bit (or 8 byte) signed integer

uint8 or unsigned 64-bit integer

a 64-bit (or 8 byte) unsigned integer

real4 or 32-bit real or float

a 32-bit (single-precision) floating-point number

real8 or 64-bit real or double

a 64-bit (double-precision) floating-point number

Example:

read from input until return -- read text typed by user

Example:

read from process mysql until end -- read available text

Example:

read into numList from socket inStream for 3 unsigned integers

Example:

read 6 unsigned 8-bit integers from socket rfb into unitSales

Example:

read 10 chars from socket "192.168.1.4:22" in 15 seconds

Related:

Write to Sockets, Write to Process, Write to Output, Write to Error Commands

Behavior: Writes data to a socket or process, or to the standard output or standard error stream. Data can be any valid SenseTalk expression. If dataType is not specified, the value of the data expression is treated as a string of characters, which is written out to the specified socket or stream.

The socketIdentifier expression must yield the identifier of a socket that was previously opened with the open socket command.

The processIdentifier expression must yield the identifier of a process that was previously opened with the open process command. The data that is written will be sent to the standard input of the process.

If as dataType is specified, the data is converted to that binary format before being written. In this case, data can be a list of numeric values, which are all converted to the same data type. See the read command for a list of the valid data types.

Syntax:

write data {as dataType} to socket socketIdentifier

write data {as dataType} to process processIdentifier

write data {as dataType} to [output | stdout | error | stderr

Example:

write "ls -l" & return to process "#4"

Example:

write "Please enter your account id: " to output

Example:

write [2,3,5,9] as 8-bit integers to socket msock

OpenSockets Function

Behavior: Returns a list of all sockets that are currently open as a result of the open socket command.

Syntax:

openSockets()

the openSockets

Example:

repeat with each item of the openSockets

if it begins with "192.168.1.12:" then close socket it

end repeat

OpenProcesses Function

Behavior: Returns a list of all processes that are currently open and available for interaction as a result of the open process command.

Syntax:

openProcesses()

the openProcesses

Example:

repeat with each item of the openProcesses

if it begins with "/usr/bin/ssh" then

write "logout" & return to process it

end if

end repeat

 

This topic was last updated on July 02, 2020, at 02:51:54 PM.

Eggplant icon Eggplantsoftware.com | Documentation Home | User Forums | Support | Copyright © 2020 Eggplant