Receive (Socket function)
Receive a string of bytes on this socket (Socket class)
%bytesReceived = socket:Receive( [Target=] string, [[MaxBytes=] number], - [[MinBytes=] number], [[Options=] string])
|%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; a positive integer no greater than 2,147,483,647. The default is 0, which means limit the received data to the larger of the Minbytes value and the declared length of Target value. If the Maxbytes argument is 0 and the Target argument is a Longstring, the received data is limited to 2,147,483,647 bytes.|
|MinBytes||This optional, name allowed, parameter is the minimum number of bytes of data to receive before the operation completes, unless the input stream ends (a Close operation by the remote), or RECVLIM is encountered. It only needs to be specified for a variable-length receive, which is fairly unusual. The default is 0, which means use the effective value of the Maxbytes argument.
The Minbytes argument must be a positive integer no greater than 2,147,483,647, and it must not exceed the effective value of the Maxbytes argument.
|Options||This optional, name allowed, parameter is an option string, which can contain either of the following:
- Receive method return values:
- Receive returns the value
-1if the socket is not OPEN and
ONRESET CONTINUEis in effect for the socket.
- Receive returns a number greater than 0 — the number of bytes received from the socket stream — if at least the Minbytes number get stored in the target. "Lengths: maximum, minimum, truncation, RECVLIM", below, explains the use of the term number of bytes received, and it discusses the Maxbytes and Minbytes arguments and other values affecting the received string.
- The return value from Receive can be less than the Minbytes argument value. This happens, for example, if there is no data remaining to be received on the connection, that is, if FIN has been received.
- Receive returns 0 to indicate that there is no more data to be received. Calling Receive (or ReceiveAndParse) again in this situation, without at the very least setting RECVLIM to a new value, results in request cancellation.
- Receive returns the value
- In general, you use Receive when the protocol in use establishes the
length of a data item before it appears in the socket stream.
The simplest case is receiving the next n bytes, where n
is the size of the target (as shown in "Examples", below).
You can use an alternative receive operation, 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 can use ReceiveAsynchronous for data for which you may have to wait as long as the timeout time before returning.
Lengths: maximum, minimum, truncation, RECVLIM
The Receive method allows you to receive either a fixed length string of bytes, or to receive some minimum length and also any additional bytes that may already be available in the socket's TCP/IP input buffer; this latter capability we call a "variable length receive."
It is important to understand that when we say "the string that is received in a call to Receive," it may be more than the string that Receive stores in the receive target. Therefore, data in the input stream that exceeds the size of the target can be discarded (or "truncated"). References to the string received by Receive are to the string stored in the target plus any subsequent bytes that are discarded. Under Sirius Mods 6.3 and later, if the target is a Longstring, no bytes would ever be discarded, since the maximum size of a Longstring is the same as the greatest number of bytes Receive will ever receive.
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 you want, 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
When RECVLIM has been set, 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
|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_recv||This corresponds to the Maxbytes argument of the Receive function call. It needs to be specified only if you wish to allow truncation, or if you wish to limit the received string to a length shorter than the size of the receive target. The number of bytes received by Receive will not exceed the effective value of this argument. The effective value of max_recv, if Maxbytes is 0 (its default), is discussed below in "Effective values of max_recv and min_recv".|
|min_recv||This corresponds to the Minbytes argument of the Receive function call. You only need to provide this argument for a variable length receive. The receive initiated by Receive will only complete if min_recv bytes are received, or if the limit to the stream (RECVLIM or len_to_end) is reached. The effective value of min_recv, if Minbytes 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 targ_size. It will always be zero, unless max_recv is greater than targ_size.|
Effective values of max_recv and min_recv
The Maxbytes and Minbytes arguments of Receive both default to 0; if they are omitted, or if they are coded as 0, their effective values are shown here:
|Item||Value when argument is 0|
|max_recv||Larger of Receive argument Minbytes and targ_size|
|min_recv||The effective value of max_recv|
Truncation can only occur if max_recv > targ_size, which cannot happen if the target is a Longstring.
A variable length receive, which is a fairly unusual operation, is only possible if min_recv differs from max_recv; therefore, you will generally not code the Minbytes argument of Receive.
Less than Minbytes available
Before Sirius Mods version 6.3, if Receive was called and the number of bytes
remaining on the connection within the remaining RECVLIM was
less than the effective value of the Minbytes argument,
Receive returned 0 to indicate this, but the receive target
was set to any partial string remaining, or to the null string if there
were none remaining (that is,
FIN has been received).
The 0 return code indicated unsuccessful completion because the
function wasn't able to do all it was asked to do (that is, return a
fixed number of bytes or a specified minimum number of bytes).
Depending on your application, this may be an error or the partial
string may be valid data.
If no bytes were discarded, you could determine the number of
bytes received by the length of the string stored in the receive target.
In Sirius Mods version 6.3 and later, if Receive is called and the number of
bytes remaining on the connection within the remaining RECVLIM is
less than the effective value of Minbytes,
Receive returns the number of bytes read.
In such a case, if the application determines that the number of bytes
returned is less than Minbytes, it knows that either RECVLIM
must have been hit or a
FIN must have been received.
Alternatively, the application can forego checking for this case and
simply wait until Receive returns a zero.
This allows a simple receive loop structure like
do while %sock:receive(target=%targ) ... end do
Though with the use of Longstrings, an application can simply receive everything up to RECVLIM or the end of a stream with a simple
%rc = %sock:receive(target=%target)
where %target is a Longstring.
In this example, exactly 5 data items of 100 bytes each are retrieved:
%grabit is string len 100 array(5) For %x from 1 to 5 %len = %sock:Receive(%grabit(%x)) If %len ne 100 then Print 'Invalid number of bytes received.' Print 'Last string received=' %grabit(%x) Print 'Partial length=' With $LEN(%grabit(%x)) End If End For