Receive (Socket function): Difference between revisions

From m204wiki
Jump to navigation Jump to search
mNo edit summary
Line 19: Line 19:
</table>
</table>
==Usage notes==
==Usage notes==
===Lengths: maximum, minimum, truncation, RECVLIM===
The <var>[[Receive (Socket function)|Receive]]</var> 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 <var>Receive</var>,"
it may be more than the string that <var>Receive</var> 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 <var>Receive</var> are to the
string stored in the target plus any subsequent bytes that are discarded.
Under <var class="product">Sirius Mods</var> 6.3 and later, if the target is a <var>Longstring</var>, no bytes
would ever be discarded, since the maximum size of a <var>Longstring</var> is the
same as the greatest number of bytes <var>Receive</var> 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:
<table class="syntaxTable">
<tr><th><var>RECVLIM</var></th>
<td>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 <var>Receive</var> and <var>ReceiveAndParse</var>) to a predetermined total number of bytes.
<var>RECVLIM</var> can be set in a <var>[[Set (Socket function)#recvlim|Set]]</var> call, and subsequent receive operations decrement from <var>RECVLIM</var> the number of bytes received, until it reaches zero (at which point a <var>Receive</var> call will return a 0, just as if a <code>FIN</code> had been received). Another <var>Receive</var> call after one returns a 0 will result in request cancellation unless <var>RECVLIM</var> is reset.
When <var>RECVLIM</var> has been set, no receive operation will use any bytes beyond the window.
A good example of the use of <var>RECVLIM</var> is obtaining a web page, whose length is (usually) specified in the <code>Content-length</code> field of the HTTP response header. </td></tr>
<tr><th>len_to_end</th>
<td>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. </td></tr>
<tr><th>max_recv</th>
<td>This corresponds to argument 3 of the <var>Receive</var> 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 <var>Receive</var> will not exceed the effective value of this argument. The effective value of <var class="term">max_recv</var>, if argument 3 is 0 (its default), is discus </td></tr>
<tr><th>min_recv</th>
<td>This corresponds to argument 4 of the <var>Receive</var> function call. You only need to provide this argument for a variable length receive. The receive initiated by <var>Receive</var> will only complete if <var class="term">min_recv</var> bytes are received, or if the limit to the stream (<var>RECVLIM</var> or <var class="term">len_to_end</var>) is reached. The effective value of min_recv, if argument 4 is 0 (its default), is discussed
below. </td></tr>
<tr><th>targ_size</th>
<td>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. </td></tr>
<tr><th>discard_len</th>
<td>This is the number of bytes received minus <var class="term">targ_size</var>. It will always be zero, unless <var class="term">max_recv</var> is greater than <var class="term">targ_size</var>. </td></tr>
</table>
Arguments three and four both default to 0; if they are omitted, or if
they are coded as 0, their effective values are shown here:
<h4>Effective values of <i>max_recv</i> and <i>min_recv</i></h4>
<table>
<tr><th>Item</th>
<th>Value when argument is 0 </th></tr>
<tr><th><i>max_recv</i></th>
<td>Larger of <var>Receive</var> argument <var>Minbytes</var> and <var class="term">targ_size</var> </td></tr>
<tr><th><i>min_recv</i></th>
<td>The effective value of <var class="term">max_recv</var> </td></tr>
</table>
'''Truncation''' can only occur if <var class="term">max_recv</var> > <var class="term">targ_size</var>, which
cannot happen if the target is a <var>Longstring</var>.
A '''variable length''' receive, which is a fairly unusual operation,
is only possible if <var class="term">min_recv</var> differs from <var class="term">max_recv</var>; therefore, you will
generally not code the <var>Minbytes</var> argument of <var>Receive</var>.
<h4>Less than Minbytes available</h4>
Before <var class="product">Sirius Mods</var> version 6.3, if <var>Receive</var> was called and the number of bytes
remaining on the connection within the remaining <var>RECVLIM</var> was
less than the effective value of the <var>Minbytes</var> argument,
<var>Receive</var> 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, <code>FIN</code> 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 <var class="product">Sirius Mods</var> version 6.3 and later, if <var>Receive</var> is called and the number of
bytes remaining on the connection within the remaining <var>RECVLIM</var> is
less than the effective value of <var>Minbytes</var>,
<var>Receive</var> returns the number of bytes read.
In such a case, if the application determines that the number of bytes
returned is less than <var>Minbytes</var>, it knows that either <var>RECVLIM</var>
must have been hit or a <code>FIN</code> must have been received.
Alternatively, the application can forego checking for this case and
simply wait until <var>Receive</var> returns a zero.
This allows a simple receive loop structure like
<p class="code"> Do While %sock:Receive(Target=%targ)
    ...
End Do
</p>
Though with the use of <var>Longstrings</var>, an application can simply receive
everything up to <var>RECVLIM</var> or the end of a stream with a simple
<p class="code"> %rc = %sock:Receive(Target=%target)
</p>
where <var class="term">%target</var> is a <var>Longstring</var>.
==Examples==
==Examples==
==See also==
==See also==


{{Template:Socket:Receive footer}}
{{Template:Socket:Receive footer}}

Revision as of 21:59, 9 December 2011

Receive a string of bytes on this socket (Socket class)


Syntax

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

Syntax terms

%BytesReceivednumber
socket Socket object
Target string
MaxBytes number
MinBytes number
Options string

Usage notes

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 FIN had been received). Another Receive call after one returns a 0 will result in request cancellation unless RECVLIM is reset.

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 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_recv This corresponds to argument 3 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 argument 3 is 0 (its default), is discus
min_recv This corresponds to argument 4 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 argument 4 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.

Arguments three and four both default to 0; if they are omitted, or if they are coded as 0, their effective values are shown here:

Effective values of max_recv and min_recv

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.

Examples

See also