ibm-information-center/dist/eclipse/plugins/i5OS.ic.apis_5.4.0.1/acceptr.htm

693 lines
22 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Copyright" content="Copyright (c) 2006 by IBM Corporation">
<title>accept_and_recv()--Wait for Connection Request and Receive the First
Message That Was Sent</title>
<!-- Begin Header Records ========================================== -->
<!-- All rights reserved. Licensed Materials Property of IBM -->
<!-- US Government Users Restricted Rights -->
<!-- Use, duplication or disclosure restricted by -->
<!-- GSA ADP Schedule Contract with IBM Corp. -->
<!-- Change History: -->
<!-- YYMMDD USERID Change description -->
<!-- Direct1 SCRIPT J converted by B2H R4.1 (346) (CMS) by V2KEA304 -->
<!-- at RCHVMW2 on 17 Feb 1999 at 11:05:09 -->
<!-- Edited by Kersten Feb 02 -->
<!-- End Header Records -->
<link rel="stylesheet" type="text/css" href="../rzahg/ic.css">
</head>
<body>
<!--Java sync-link-->
<script type="text/javascript" language="Javascript" src="../rzahg/synch.js">
</script>
<a name="Top_Of_Page"></a>
<h2>accept_and_recv()--Wait for Connection Request and Receive the First
Message That Was Sent</h2>
<div class="box" style="width: 70%;">
<br>
&nbsp;&nbsp;BSD 4.3 Syntax<br>
<pre>
#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
int accept_and_recv(int <em>listen_socket_descriptor</em>,
int *<em>accept_socket_descriptor</em>,
struct sockaddr *<em>remote_address</em>,
size_t *<em>remote_address_length</em>,
struct sockaddr *<em>local_address</em>,
size_t *<em>local_address_length</em>,
void *<em>buffer</em>,
size_t <em>buffer_length</em>)
</pre>
<br>
&nbsp;&nbsp;Service Program Name: QSOSRV1<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Default Public Authority: *USE<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Threadsafe: Yes<br>
<!-- iddvc RMBR -->
<br>
</div>
<br>
<div class="box" style="width: 70%;">
<br>
&nbsp;&nbsp;<a href="_xopen_source.htm">UNIX 98 Compatible Syntax</a><br>
<pre>
#define _XOPEN_SOURCE 520
#include &lt;sys/socket.h&gt;
int accept_and_recv(int <em>listen_socket_descriptor</em>,
int *<em>accept_socket_descriptor</em>,
struct sockaddr *<em>remote_address</em>,
socklen_t *<em>remote_address_length</em>,
struct sockaddr *<em>local_address</em>,
socklen_t *<em>local_address_length</em>,
void *<em>buffer</em>,
size_t <em>buffer_length</em>)
</pre>
<br>
&nbsp;&nbsp;Service Program Name: QSOSRV1<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Default Public Authority: *USE<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Threadsafe: Yes<br>
<!-- iddvc RMBR -->
<br>
</div>
<p>The <em>accept_and_recv()</em> function is used to wait for an incoming
connection request, receive the first message from the peer, and return the
local and remote socket addresses associated with the connection.</p>
<p><em>accept_and_recv()</em> is used with connection-oriented sockets that
have an address family of <samp>AF_INET</samp> or <samp>AF_INET6</samp> and a socket type of <samp>SOCK_STREAM</samp>.</p>
<p>The <em>accept_and_recv()</em> API is a combination of the
<em>accept()</em>, <em>getsockname()</em>, and <em>recv()</em> socket APIs.
Socket applications that use these three APIs can obtain improved performance
by using <em>accept_and_recv()</em>.</p>
<p> There are two versions of
the API, as shown above. The base i5/OS<SUP>(TM)</SUP> API uses BSD 4.3 structures and
syntax. The other uses syntax and structures compatible with the UNIX 98
programming interface specifications. You can select the UNIX 98 compatible
interface with the <a href="_xopen_source.htm">_XOPEN_SOURCE</a> macro.</p>
<br>
<h3>Parameters</h3>
<dl>
<dt><strong>listen_socket_descriptor</strong></dt>
<dd>(Input) The descriptor of the socket on which to wait. This parameter
specifies the socket that has issued a successful call to
<em>listen()</em>.<br>
<br>
</dd>
<dt><strong>accept_socket_descriptor</strong></dt>
<dd>(Input/Output) A pointer to an integer that specifies the socket descriptor
on which to accept the incoming connection. This socket must not be bound or
connected. The use of this parameter lets the application reuse the accepting
socket.
<p>If a pointer to a value of -1 is passed in for this parameter, a new
descriptor in the process's descriptor table will be allocated for incoming
connection. The socket descriptor for a new connection will be returned to the
application by this parameter. It is recommended that a value of -1 be used on
the first call to <em>accept_and_recv()</em>. See the <a href=
"#USAGE_NOTES">Usage Notes</a> for additional information.</p>
</dd>
<dt><strong>remote_address</strong></dt>
<dd>(Output) A pointer to a buffer of type <strong>struct sockaddr</strong> in
which the address from which the connection request was received is stored. The
structure <strong>sockaddr</strong> is defined in
<strong>&lt;sys/socket.h&gt;</strong>.
<p> The BSD 4.3 structure
is:</p>
<pre>
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
</pre>
<p>The BSD 4.4/UNIX 98 compatible structure is:</p>
<pre>
typedef uchar sa_family_t;
struct sockaddr {
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};
</pre>
<p>The BSD 4.4 <em>sa_len</em> field is the length of the address. The <em>sa_family</em> field identifies
the address family to which the address belongs, and <em>sa_data</em> is the
address whose format is dependent on the address family.</p>
<p> <strong>Note:</strong> See
the usage notes about using different address families with
<strong>sockaddr_storage</strong>.</p>
</dd>
<dt><strong>remote_address_length</strong></dt>
<dd>(Input/Output) This parameter is a value-result field. The caller passes a
pointer to the length of the <em>remote_address</em> parameter. On return from
the call, <em>remote_address_length</em> contains the actual length of the
address from which the connection request was received.<br>
<br>
</dd>
<dt><strong>local_address</strong></dt>
<dd>(Output) A pointer to a buffer of type <strong>struct sockaddr</strong> in
which the local address over which the connection request was received is
stored. The structure <strong>sockaddr</strong> is defined in
<strong>&lt;sys/socket.h&gt;</strong>.
<p> The BSD 4.3 structure
is:</p>
<pre>
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
</pre>
<p>The BSD 4.4/UNIX 98 compatible structure is:</p>
<pre>
typedef uchar sa_family_t;
struct sockaddr {
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};
</pre>
<p>The BSD 4.4 <em>sa_len</em> field is the length of the address. The <em>sa_family</em> field identifies
the address family to which the address belongs, and <em>sa_data</em> is the
address whose format is dependent on the address family.</p>
<p> <strong>Note:</strong> See
the usage notes about using different address families with
<strong>sockaddr_storage</strong>.</p>
</dd>
<dt><strong>local_address_length</strong></dt>
<dd>(Input/Output) This parameter is a value-result field. The caller passes a
pointer to the length of the <em>local_address</em> parameter. On return from
the call, <em>local_address_length</em> contains the actual length of the local
address over which the connection request was received.<br>
<br>
</dd>
<dt><strong>buffer</strong></dt>
<dd>(Output) The pointer to the buffer in which the data that is to be read is
stored. If a NULL pointer is passed in for this parameter, the receive
operation is not performed and the <em>accept_and_recv()</em> function
completes when the incoming connection is received.<br>
<br>
</dd>
<dt><strong>buffer_length</strong></dt>
<dd>(Input) The length in bytes of the buffer pointed to by the <em>buffer</em>
parameter.</dd>
</dl>
<br>
<h3>Authorities</h3>
<p>If IP over SNA is being used, *CHANGE authority to the APPC device is
required.</p>
<br>
<h3>Return Value</h3>
<p><em>accept_and_recv()</em> returns an integer. Possible values are:</p>
<ul>
<li>-1 (unsuccessful call)<br>
<br>
</li>
<li>n (successful call), where n is the number of bytes received.</li>
</ul>
<br>
<h3>Error Conditions</h3>
<p>When <em>accept_and_recv()</em> fails, <em>errno</em> can be set to one of
the following:</p>
<table cellpadding="5">
<!-- cols="20 80" -->
<tr>
<td align="left" valign="top"><em>[EACCES]</em></td>
<td align="left" valign="top">Permission denied.
<p>A connection indication request was received on the socket referenced by the
<em>listen_socket_descriptor</em> parameter, but the process that issued the
<em>accept_and_recv()</em> call did not have the appropriate privileges
required to handle the request. The connection indication request is reset by
the system.</p>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EBADF]</em></td>
<td align="left" valign="top">Descriptor not valid.
<p>Either the <em>listen_socket_descriptor</em> or the descriptor pointed to by
the <em>accept_socket_descriptor</em> parameter is not a valid socket
descriptor.</p>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[ECONNABORTED]</em></td>
<td align="left" valign="top">Connection ended abnormally.
<p>An <em>accept_and_recv()</em> was issued on a socket for which receive
operations have been disallowed (due to a <em>shutdown()</em> call).</p>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EFAULT]</em></td>
<td align="left" valign="top">Bad address.
<p>System detected an address that was not valid while attempting to access the
<em>accept_socket_descriptor</em>, <em>remote_address</em>,
<em>remote_address_length</em>, <em>local_address</em>,
<em>local_address_length</em>, or <em>buffer</em> parameter.</p>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EINTR]</em></td>
<td align="left" valign="top">Interrupted function call.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EINVAL]</em></td>
<td align="left" valign="top">Parameter not valid.
<p>This error code indicates one of the following:</p>
<ul>
<li>A <em>listen()</em> has not been issued against the socket referenced by
the <em>listen_socket_descriptor</em> parameter.<br>
<br>
</li>
<li>The socket referenced by the <em>accept_socket_descriptor</em> parameter
has been bound to a local address.<br>
<br>
</li>
<li>The <em>accept_socket_descriptor</em> does not have the same address family
and socket type as the <em>listen_socket_descriptor</em>.<br>
<br>
</li>
<li>The <em>accept_socket_descriptor</em> parameter is set to a value that is
less than -1.<br>
</li>
</ul>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EIO]</em></td>
<td align="left" valign="top">Input/output error.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EISCONN]</em></td>
<td align="left" valign="top">A connection has already been established.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EMFILE]</em></td>
<td align="left" valign="top">Too many descriptions for this process.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[ENFILE]</em></td>
<td align="left" valign="top">Too many descriptions in system.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[ENOBUFS]</em></td>
<td align="left" valign="top">There is not enough buffer space for the
requested operation.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[ENOTSOCK]</em></td>
<td align="left" valign="top">The specified descriptor does not reference a
socket.
<p>Either the <em>listen_socket_descriptor</em> or the descriptor pointed to by
the <em>accept_socket_descriptor</em> parameter is not a valid socket
descriptor.</p>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EOPNOTSUPP]</em></td>
<td align="left" valign="top">Operation not supported.
<p>This error code indicates one of the following:</p>
<ul>
<li>The <em>listen_socket_descriptor</em> parameter references a socket that
does not support the <em>accept_and_recv()</em> function. The
<em>accept_and_recv()</em> function is only valid on sockets that have an
address family of <samp>AF_INET</samp> or <samp>AF_INET6</samp> and a socket type of <samp>SOCK_STREAM</samp>.<br>
<br>
</li>
<li>The <samp>O_NONBLOCK</samp> option is set for the
<em>listen_socket_descriptor</em> or the descriptor pointed to by the
<em>accept_socket_descriptor</em> parameter. Non-blocking is not supported for
<em>accept_and_recv()</em>.<br>
</li>
</ul>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EUNATCH]</em></td>
<td align="left" valign="top">The protocol required to support the specified
address family is not available at this time.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EUNKNOWN]</em></td>
<td align="left" valign="top">Unknown system state.</td>
</tr>
</table>
<br>
<br>
<h3>Error Messages</h3>
<table cellpadding="5" width="100%">
<!-- cols="15 85" -->
<tr>
<th align="left" valign="top">Message ID</th>
<th align="left" valign="top">Error Message Text</th>
</tr>
<tr>
<td width="15%" valign="top">CPE3418 E</td>
<td width="85%" valign="top">Possible APAR condition or hardware failure.</td>
</tr>
<tr>
<td align="left" valign="top">CPF9872 E</td>
<td align="left" valign="top">Program or service program &amp;1 in library
&amp;2 ended. Reason code &amp;3.</td>
</tr>
<tr>
<td align="left" valign="top">CPFA081 E</td>
<td align="left" valign="top">Unable to set return value or error code.</td>
</tr>
</table>
<br>
<br>
<h3><a name="USAGE_NOTES">Usage Notes</a></h3>
<ol>
<li>The <em>accept_and_recv()</em> function is only valid on sockets that have
an address family of AF_INET or
AF_INET6 and a socket type of
SOCK_STREAM. If the <em>listen_socket_descriptor</em> does not have the correct
address family and socket type, -1 is returned and the <em>errno</em> value is
set to EOPNOTSUPP.<br>
<br>
</li>
<li>Non-blocking mode is not supported for this function. If O_NONBLOCK is set
on the <em>listen_socket_descriptor</em> parameter or on the descriptor pointed
to by the <em>accept_socket_descriptor</em> parameter, -1 is returned and the
<em>errno</em> value is set to EOPNOTSUPP.<br>
<br>
</li>
<li>If the <em>remote_address</em> parameter is set to a NULL pointer, the
address from which the connection request was received is not returned. If the
length of the remote address to be returned exceeds the length that was
specified by the <em>remote_address_length</em> parameter, the returned address
will be truncated.<br>
<br>
</li>
<li>If the <em>local_address</em> parameter is set to a NULL pointer, the local
address to which the socket is bound is not returned. If the length of the
local address to be returned exceeds the length that was specified by the
<em>local_address_length</em> parameter, the returned address will be
truncated.<br>
<br>
</li>
<li>If the <em>buffer</em> parameter is set to a NULL pointer or the
<em>buffer_length</em> parameter is set to value of 0, the receive operation is
not performed and the <em>accept_and_recv()</em> function completes when the
incoming connection is received.<br>
<br>
</li>
<li>If a pointer to a value of -1 is passed in for the
<em>accept_socket_descriptor</em> parameter, the following attributes are
inherited by the socket descriptor that is returned by the
<em>accept_and_recv()</em> call:
<ul>
<li>All socket options with a level of SOL_SOCKET.<br>
<br>
</li>
<li>The status flags:
<ul>
<li>Asynchronous flag (set or reset either by the <em>ioctl()</em> call with
the FIOASYNC request or by the <em>fcntl()</em> call with the F_SETFL command
and the status flag set to FASYNC).</li>
</ul>
<br>
<br>
</li>
<li>The process ID or process group ID that is to receive SIGIO or SIGURG
signals (set or reset by either the <em>ioctl()</em> call with the FIOSETOWN or
the SIOCSPGRP request, or by the <em>fcntl()</em> call with the F_SETOWN
command).</li>
</ul>
<br>
<br>
</li>
<li>The <em>accept_and_recv()</em> function allows an application to reuse an
existing socket descriptor. If a socket descriptor is specified for the
<em>accept_socket_descriptor</em> parameter, it must not be bound or connected
and it must have the same address family and socket type as the
<em>listen_socket_descriptor</em>. The socket descriptor that is passed in for
the <em>accept_socket_descriptor</em> parameter can be obtained by either
calling <em>socket()</em> or by specifying the SF_REUSE flag on the
<em>flags</em> parameter of the <em>send_file()</em> function.
<p>If an application specifies a pointer to an unbound and unconnected socket
descriptor for the <em>accept_socket_descriptor</em> parameter that is the same
address family and socket type as the <em>listen_socket_descriptor</em>, the
<em>accept_and_recv()</em> function will try to use the
<em>accept_socket_descriptor</em> for the incoming connection. If the
<em>accept_socket_descriptor</em> cannot be used for the incoming connection,
the descriptor for that socket will be closed and a new socket will be created
for the incoming connection. The new socket may have a different descriptor
number associated with it. This means that the value that is returned by the
<em>accept_socket_descriptor</em> parameter may not be the same value that was
specified by the application when the <em>accept_and_recv()</em> function was
called.</p>
<p>The ability to reuse an existing socket is not supported on all platforms.
Therefore, it is recommended that a pointer to a value of -1 be passed in for
the <em>accept_socket_descriptor</em> parameter. If socket reuse is not
supported and the <em>send_file()</em> API is called with the <em>flags</em>
parameter set to SF_REUSE, the socket connection will be closed and the socket
descriptor will be set to -1 by the <em>send_file()</em> API. If socket reuse
is supported, then the connection will be closed and the socket descriptor will
be reset so that it can be used again. Regardless of whether socket reuse is
supported or not, the application can pass its socket descriptor variable into
the <em>accept_and_recv()</em> function as the
<em>accept_socket_descriptor</em> parameter.</p>
</li>
<li>The structure
<strong>sockaddr</strong> is a generic structure used for any address family
but it is only 16 bytes long. The actual address returned for some address
families may be much larger. You should declare storage for the address with
the structure <strong>sockaddr_storage</strong>. This structure is large enough
and aligned for any protocol-specific structure. It may then be cast as
<strong>sockaddr</strong> structure for use on the APIs. The <em>ss_family</em>
field of the <strong>sockaddr_storage</strong> will always align with the
family field of any protocol-specific structure.
<p>The BSD 4.3 structure is:</p>
<pre>
#define _SS_MAXSIZE 304
#define _SS_ALIGNSIZE (sizeof (char*))
#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(sa_family_t))
#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(sa_family_t)+
_SS_PAD1SIZE + _SS_ALIGNSIZE))
struct sockaddr_storage {
sa_family_t ss_family;
char _ss_pad1[_SS_PAD1SIZE];
char* _ss_align;
char _ss_pad2[_SS_PAD2SIZE];
};
</pre>
<p>The BSD 4.4/UNIX 98 compatible structure is:</p>
<pre>
#define _SS_MAXSIZE 304
#define _SS_ALIGNSIZE (sizeof (char*))
#define _SS_PAD1SIZE (_SS_ALIGNSIZE - (sizeof(uint8_t) + sizeof(sa_family_t)))
#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(uint8_t) + sizeof(sa_family_t)+
_SS_PAD1SIZE + _SS_ALIGNSIZE))
struct sockaddr_storage {
uint8_t ss_len;
sa_family_t ss_family;
char _ss_pad1[_SS_PAD1SIZE];
char* _ss_align;
char _ss_pad2[_SS_PAD2SIZE];
};
</pre>
</li>
<li>To take full advantage of the performance improvement offered by the
<em>accept_and_recv()</em> API, a multiple accept server model needs to be used
by the application. In this model the server will do a <em>socket()</em>,
<em>bind()</em>, and <em>listen()</em> as currently is done. The server will
then give the listening socket to multiple jobs or threads. Each job or thread
will then call <em>accept_and_recv()</em> using the same listening socket. When
a connection request comes in, only one of the jobs or threads would wake
up.<br>
<br>
</li>
<li>If a successful <em>Rbind()</em> has been performed on the listening
socket, then a new connection is not returned, but rather an inbound connection
occurs on the same listening socket. The descriptor number returned is
different, but it actually refers to the same connection referred to by the
listening socket.</li>
<li>When you develop in C-based
languages and an application is compiled with the _XOPEN_SOURCE macro defined
to the value 520 or greater, the <em>accept_and_recv()</em> API is mapped to
<em>qso_accept_and_recv98()</em>.</li>
</ol>
<br>
<h3>Related Information</h3>
<ul>
<li><a href=
"_xopen_source.htm">_XOPEN_SOURCE</a>--Using _XOPEN_SOURCE for the UNIX 98
compatible interface<br>
<br>
</li>
<li><a href="accept.htm">accept()</a>--Wait for Connection Request and Make
Connection<br>
<br>
</li>
<li><a href="gsockn.htm">getsockname()</a>--Retrieve Local Address of
Socket<br>
<br>
</li>
<li><a href="recv.htm">recv()</a>--Receive Data<br>
<br>
</li>
<li><a href="sendfile.htm">send_file()</a>--Send a File over a Socket
Connection</li>
</ul>
<br>
<hr>
API introduced: V4R3
<hr>
<center>
<table cellpadding="2" cellspacing="2">
<tr align="center">
<td valign="middle" align="center"><a href="#Top_Of_Page">Top</a> | <a href=
"unix.htm">UNIX-Type APIs</a> | <a href="aplist.htm">APIs by category</a></td>
</tr>
</table></center>
</body>
</html>