ReceiveAndParse (Socket function)

From m204wiki
Revision as of 20:43, 23 September 2014 by JAL (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Receive bytes up to a given string (Socket class)


This method receives a string over a Janus Sockets connection. It is designed for a string whose length is not known beforehand but which is terminated by a known string or by one of a known set of strings. The ReceiveAndParse function has an effect similar to $Sock_RecvPrs.

Syntax

%bytesReceived = socket:ReceiveAndParse( [Target=] string, - [[MaxBytes=] number], - [[ParseTokenIndex=] number], - [[Options=] string])

Syntax terms

%BytesReceived A numeric string to contain the count of the number of bytes received, or to contain 0, if the operation cannot be performed.
socket A variable or an expression that is a reference to a Socket object.
Target This name allowed parameter is a %variable or an IMAGE item that is the target of the receive operation. It is referred to as the "receive target." Since you may request that some bytes from the socket stream be discarded, the length of the string stored in this target may be less than the %BytesReceived value.
MaxBytes This optional, name allowed, parameter is the maximum number of bytes of data to receive, less the length of the separator string. This optional argument defaults to 0, which means limit the received data (less separator) to the declared length of the receive target.

If the MaxBytes argument is 0 and the Target argument value is a Longstring, the received data is limited to 2,147,483,647 bytes. The MaxBytes argument value must not exceed 2,147,483,647. MaxBytes may have the special value -1 to indicate there is no limit to the number of bytes received.

ParseTokenIndex This optional, name allowed, parameter is a %variable or IMAGE item to store the index number (positive integer) of the parse token found in the received data. The ParseTokenIndex value is set to 0 if no token is found within RECVLIM bytes, or if it is not found after more than the number of data bytes specified by the effective value of the MaxBytes argument.
Options This optional, name allowed, parameter is an option string, which can contain either of the following:
BINARY Regardless of the socket's BINARY or CHAR port parameter, data is not translated when saved in the receive target. The received string can be translated later in the program using the TranIn method.
CHAR Regardless of the socket's BINARY or CHAR parameter, data is translated when saved in the receive target. The translation is specified by the input table defined by the socket's XTAB port parameter.
PRSTOK [AMBIG|]hexstr[|hexstr]... A set of parse tokens that override the current parse tokens on the socket.

Whether it is set on the port definition or by the Set or ReceiveAndParse methods, PRSTOK must not be NONE, or ReceiveAndParse will fail.

Usage notes

  • ReceiveAndParse return values:
    • ReceiveAndParse returns the value -1 if the socket is not open and ONRESET CONTINUE is in effect for the socket.
    • ReceiveAndParse returns a number greater than 0 which is the number of bytes received from of the socket stream. "Lengths: maximum, truncation, RECVLIM" explains the use of the term number of bytes received, and it discusses the maxrecvp argument and other values affecting the received string.
    • ReceiveAndParse returns zero to indicate there is no data remaining to be received on the connection, that is, if FIN has been received or the RECVLIM has been reached.
  • In general, you use ReceiveAndParse for a data item whose length is unknown beforehand, but rather is terminated by a known string (or one of a known set of strings). You use the alternate receive operation, Receive, when the protocol in use establishes the length of a data item before it appears in the socket stream.
  • The %prsindx argument is used if there is more than one alternative in the PRSTOK set, and you need to distinguish which alternative terminated the received value. For example, with the input stream of X'36370D38390D', the following expression will store the value 2 in the variable %prs.

    %sk:ReceiveAndParse(%str, , %prs, 'PRSTOK AMBIG|0D0A|0D|0A')

    Note that this example uses ambiguous PRSTOK strings (0D is a prefix of 0D0A). Considerations for this are discussed in "Ambiguous PRSTOK strings".

  • The PRSTOK separators are chosen to match the protocol and data streams that are used with your application. One of the considerations, of course, is that a separator should not occur in the "normal" data received by your application. If that is unavoidable, you will need to use an "escaping" mechanism; for example, you could use the ASCII ESC character (hexadecimal 1B) to indicate that it precedes a character that is to be taken literally. For example, if the data contains non-separator instances of CR and ESC:

    %junk string len 1 %sok:Set('PRSTOK', '0D|1B') Repeat %r = %sok:ReceiveAndParse(%targ, %sep) If %sep eq 2 then %r = %sok:Receive(%junk) %targ = %targ With %junk End If ...

Lengths: maximum, truncation, RECVLIM

The ReceiveAndParse function allows you to locate a separator string, and to store all or part of the string before the separator into the receive target. It is important to understand that when we say "the string that is received in a call to ReceiveAndParse", it may be more than the string that ReceiveAndParse stores in the receive target. This is for the following two reasons:

  1. The separator string is part of the string received, but it is not stored in the receive target.
  2. The string before the separator may exceed the size of the target, and thus can be partially discarded (or "truncated").

References to the string received by ReceiveAndParse are to the string stored in the target plus any subsequent bytes that are discarded, plus the separator string.

There are several values that control the length of the string received. They will be discussed in this section, using the following terms:

RECVLIM This specifies the number of bytes remaining in the "receive window".

A value of zero means there is no limit to the window. The purpose of this window is to allow you to limit a series of receive operations (using, if desired, a mixture of Receive and ReceiveAndParse) to a predetermined total number of bytes. RECVLIM can be set in a Set call, and subsequent receive operations decrement from RECVLIM the number of bytes received, until it reaches zero, at which point a Receive call will return a 0 just as if a FIN had been received. Another Receive call after one returns a 0 will result in request cancellation unless RECVLIM is reset. When RECVLIM is greater than zero, no receive operation will use any bytes beyond the window.

A good example of the use of RECVLIM is obtaining a web page, whose length

is (usually) specified in the Content-length field of the HTTP response header.
len_to_end When a receive operation is performed, the received string is

of course limited to the total remaining bytes in the stream that the remote end sent before issuing a close operation. Although this value is not known ahead of time, when describing the

operation of receive we use this term to indicate various cases.
max_recvp This corresponds to the Maxbytes argument of the ReceiveAndParse function call.

It needs to be specified only if you wish to allow truncation, or if you wish to limit the string stored in the received target to less than the declared the size of the target. You can specify that an unlimited number of bytes can be discarded by specifying -1 as the Maxbytes argument, making the effective value "infinite".

The number of bytes received by ReceiveAndParse will not exceed the effective value of this argument plus the length of the separator string. The effective value of max_recvp, if Maxbytes is 0 (its default) or omitted, is targ_size.

Truncation can only occur if max_recvp > targ_size, which cannot happen if the target is a Longstring.

If a separator string is not found due to a limit imposed by either RECVLIM, len_to_end, or max_recvp, then zero is stored in the parse index target (the ParseTokenIndex argument).

targ_size The size of the target is used in calculating various defaults

of the other values here, and it also obviously limits the number of

bytes stored in the target and so affects the number of bytes discarded.
discard_len This is the number of bytes received, minus the length of the

separator string, minus targ_size. It will always be zero, unless

max_recvp is greater than targ_size

Example

The following example shows part of a program that communicates with a remote web server and which parses and prints the returned HTML stream. Note that the second argument to ReceiveAndParse is -1, which means that there is no limit to the length of each line parsed, hence no limit to the number of bytes discarded at the end of the line: only the first 78 bytes (the size of %s) of each line of HTML is examined by the User Language program.

%s = %sock:Set('PRSTOK', '0D0A|0A|0D') Repeat %rc = %sock:ReceiveAndParse(%s, -1) Print %s If %rc le 0 then Loop End End If End Repeat %rc = %sock:Close

See also