From m204wiki
Jump to navigation Jump to search

Receive parsed string

Note: Many $functions have been deprecated in favor of Object Oriented methods. The OO equivalent for $Sock_RecvPrs is the ReceiveAndParse method.

$Sock_RecvPrs receives, over a Janus Sockets connection, 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.

$Sock_RecvPrs is also callable.


[%num =] = $Sock_RecvPrs(sockNum, %recv_targ, [maxrecvp], [prsindx], [opts])

Syntax terms

%num A numeric value that is the number of bytes received, or, if the operation could not be performed as requested, a 0 value. For more details, see $Sock_RecvPrs return values.
sockNum The socket number.
%recv_targ A %variable or an IMAGE item (and never a SOUL class variable). This argument is the target of the receive operation, and is referred to as the "receive target." You may request that some bytes from the socket stream can be discarded, so the length of the string stored in this target may be less than the value returned by $Sock_RecvPrs.
maxrecvp This optional argument, the maximum number of bytes of data to receive, less the length of the separator string, must be from 0 to 2,147,483,647, or must be the special value -1, which indicates there is no limit to the number of bytes received.

The default is 0, which means limit the received data (less separator) to to the declared length of the receive target. If this argument is 0 and the receive argument is a Longstring, the received data is limited to 2,147,483,647 bytes.

prsindx This optional argument is is a %variable or IMAGE item in which the index number (> 0) of the parse token found is stored. This variable 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 maxrecvp argument.
opts This optional argument is an option string which can contain any of the following:
BINARY This indicates that regardless of the socket's BINARY or CHAR parameter, data is not translated when saved in the receive target. The received string can be translated later in the program using the $Sock_Tran_In function.
CHAR This indicates that 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 parameter.
PRSTOK [AMBIG|]hexstr[|hexstr]... This is a set of parse tokens which override the parse tokens set on the socket. Whether it is set on the port definition, via $Sock_Set, or as an argument on the $Sock_RecvPrs function, PRSTOK must not be NONE when using $Sock_RecvPrs.

$Sock_RecvPrs return values

  • $Sock_RecvPrs returns the value -1 if the socket is not open and ONRESET CONTINUE is in effect for the socket.
  • $Sock_RecvPrs returns a number greater than 0 which is the number of bytes received from of the socket stream. Lengths: maximum, truncation, RECVLIM explains how the term number of bytes received is used, and discusses the maxrecvp argument and other values affecting the received string.
  • $Sock_RecvPrs 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.

Usage notes

  • You use $Sock_RecvPrs 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). In general, you use the alternate receive operation, $Sock_Recv, when the protocol in use establishes the length of a data item before it appears in the socket stream.
  • The prsindx argument is used in case there is more than one alternative in the PRSTOK setting, and you need to distinguish which one of them 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.

    $Sock_RecvPrs(%sk, %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 %r = $Sock_Set(%sok, 'PRSTOK', '0D|1B') Repeat %r = $Sock_RecvPrs(%sok, %targ, %sep) If %sep Eq 2 Then %r = $Sock_Recv(%sok, %junk) %targ = %targ With %junk End If ...


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 third argument to $Sock_RecvPrs 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 SOUL program.

A complete version of this program is shown in Simple echo of HTTP/HTML. See Simple echo of HTTP/HTML for another complete program, which does not discard any received data.

%s = $Sock_Set(%socket, 'PRSTOK', '0D0A|0A|0D') Repeat %rc = $Sock_RecvPrs(%socket, %s, -1) Print %s If %rc LE 0 Then Loop End End If End Repeat %rc = $Sock_Close(%socket)

Lengths: maximum, truncation, RECVLIM

The $Sock_RecvPrs 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 $Sock_RecvPrs", it may be more than the string that $Sock_RecvPrs 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 $Sock_RecvPrs are to the string stored in the target plus any subsequent bytes that are discarded, plus the separator string. Several of the values that control the length of the string received are 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 you want, a mixture of $Sock_Recv and $Sock_RecvPrs) to a predetermined total number of bytes. RECVLIM can be set in a $Sock_Set call, and subsequent receive operations decrement from RECVLIM the number of bytes received, until it reaches zero (at which point a$Sock_Recv call will return a 0, just as if a FIN had been received.

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, this term is used to indicate various cases.
max_recvp This corresponds to the maxrecvp argument of the $Sock_RecvPrs function call. It needs to be specified only if you want to allow truncation, or if you want to limit the received string to a length less than the declared size of the target.

You can specify that an unlimited number of bytes can be discarded by specifying -1 as the maxrecvp argument of $Sock_RecvPrs, making the effective value "infinite." The number of bytes received by $Sock_RecvPrs will not exceed the effective value of this argument plus the length of the separator string. The effective value of max_recvp if the maxrecvp argument of $Sock_RecvPrs is 0 (its default), is discussed below.

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.

Argument max_recvp defaults to 0; if they are omitted, or if it is coded as 0, its effective value is shown here:

Item Value when argument is 0
maxrecvp argument of $Sock_RecvPrs 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 RECVLIM, len_to_end, or max_recvp, then zero is stored in the parse index target (the %prsindx argument).