Syntax
#include <sys/types.h>
#include <sys/socket.h>
int accept_and_recv(int listen_socket_descriptor,
int *accept_socket_descriptor,
struct sockaddr *remote_address,
size_t *remote_address_length,
struct sockaddr *local_address,
size_t *local_address_length,
void *buffer,
size_t buffer_length)
Threadsafe: Yes
|
The accept_and_recv() 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.
accept_and_recv() is used with connection-oriented sockets that have an address
family of AF_INET and a socket type of SOCK_STREAM.
The accept_and_recv() API is a combination of the accept(), getsockname(), and
recv() socket APIs. Socket applications that use these three APIs can
obtain improved performance by using accept_and_recv().
Parameters
- listen_socket_descriptor
- (Input) The descriptor of the socket on which to wait. This
parameter specifies the socket that has issued a successful call to
listen().
- accept_socket_descriptor
- (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.
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 accept_and_recv(). See the Usage Notes for
additional information.
- remote_address
- (Output) A pointer to a buffer of type struct sockaddr
in which the address from which the connection request was received
is stored. The structure sockaddr is defined in <sys/socket.h>.
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
The sa_family field identifies the
address family to which the address belongs,
and sa_data is the address whose format is
dependent on the address family.
- remote_address_length
- (Input/Output) This parameter is a value-result field. The caller
passes a pointer to the length of the remote_address parameter. On return from
the call, remote_address_length contains the actual length of the address from
which the connection request was received.
- local_address
- (Output) A pointer to a buffer of type struct sockaddr
in which the local address over which the connection request was received
is stored. The structure sockaddr is defined in <sys/socket.h>.
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
The sa_family field identifies the
address family to which the address belongs,
and sa_data is the address whose format is
dependent on the address family.
- local_address_length
- (Input/Output) This parameter is a value-result field. The caller
passes a pointer to the length of the local_address parameter. On return from
the call, local_address_length contains the actual length of the local address
over which the connection request was received.
- buffer
- (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 accept_and_recv() function completes
when the incoming connection is received.
- buffer_length
- (Input) The length in bytes of the buffer pointed to by the buffer
parameter.
Authorities
If IP over SNA is being used, *CHANGE authority to the APPC device
is required.
Return Value
accept_and_recv() returns an integer. Possible values are:
- -1 (unsuccessful call)
- n (successful call), where n is the number of bytes received.
Error Conditions
When accept_and_recv() fails, errno can be set to one of the following:
- [EACCES]
- Permission denied.
A connection indication request was received on the socket referenced by
the listen_socket_descriptor parameter, but the process that issued the accept_and_recv() call
did not have the appropriate privileges required to handle the request.
The connection indication request is reset by the system.
- [EBADF]
- Descriptor not valid.
Either the listen_socket_descriptor or the descriptor pointed to by the accept_socket_descriptor
parameter is not a valid socket descriptor.
- [ECONNABORTED]
- Connection ended abnormally.
An accept_and_recv() was issued on a socket for which receive operations have been
disallowed (due to a shutdown() call).
- [EFAULT]
- Bad address.
System detected an address that was not valid while attempting to
access the accept_socket_descriptor, remote_address, remote_address_length, local_address, local_address_length,
or buffer parameter.
- [EINTR]
- Interrupted function call.
- [EINVAL]
- Parameter not valid.
This error code indicates one of the following:
-
A listen() has not been issued against the socket referenced by
the listen_socket_descriptor parameter.
-
The socket referenced by the accept_socket_descriptor parameter has been bound to a
local address.
-
The accept_socket_descriptor does not have the same address family and socket type as
the listen_socket_descriptor.
-
The accept_socket_descriptor parameter is set to a value that is less than -1.
- [EIO]
- Input/output error.
- [EISCONN]
- A connection has already been established.
- [EMFILE]
- Too many descriptions for this process.
- [ENFILE]
- Too many descriptions in system.
- [ENOBUFS]
- There is not enough buffer space for the requested operation.
- [ENOTSOCK]
- The specified descriptor does not reference a socket.
Either the listen_socket_descriptor or the descriptor pointed to by the accept_socket_descriptor
parameter is not a valid socket descriptor.
- [EOPNOTSUPP]
- Operation not supported.
This error code indicates one of the following:
-
The listen_socket_descriptor parameter references a socket that does not support the
accept_and_recv() function. The accept_and_recv() function is only valid on sockets that
have an address family of AF_INET and a socket type of SOCK_STREAM.
-
The O_NONBLOCK option is set for the listen_socket_descriptor or the descriptor pointed
to by the accept_socket_descriptor parameter. Non-blocking is not supported for
accept_and_recv().
- [EUNATCH]
- The protocol required to support the specified address family is
not available at this time.
- [EUNKNOWN]
- Unknown system state.
Error Messages
- CPE3418 E
- Possible APAR condition or hardware failure.
- CPF9872 E
- Program or service program &1
in library &2 ended. Reason code &3.
- CPFA081 E
- Unable to set return value or error code.
Usage Notes
-
The accept_and_recv() function is only valid on sockets that have an address family
of AF_INET and a socket type of SOCK_STREAM. If the listen_socket_descriptor does not
have the correct address family and socket type, -1 is returned and
the errno value is set to EOPNOTSUPP.
-
Non-blocking mode is not supported for this function. If O_NONBLOCK
is set on the listen_socket_descriptor parameter or on the descriptor pointed to by the
accept_socket_descriptor parameter, -1 is returned and the errno value is set to
EOPNOTSUPP.
-
If the remote_address 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 remote_address_length parameter, the returned address will be truncated.
-
If the local_address 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
local_address_length parameter, the returned address will be truncated.
-
If the buffer parameter is set to a NULL pointer or the buffer_length
parameter is set to value of 0, the receive operation is not performed and
the accept_and_recv() function completes when the incoming connection is received.
-
If a pointer to a value of -1 is passed in for the accept_socket_descriptor parameter,
the following attributes are inherited by the socket descriptor that is
returned by the accept_and_recv() call:
- All socket options with a level of SOL_SOCKET.
- The status flags:
- Asynchronous flag (set or reset either by the ioctl() call
with the FIOASYNC request or by the fcntl() call with the
F_SETFL command and the status flag set to FASYNC).
- The process ID or process group ID that is to
receive SIGIO or SIGURG signals (set or reset by either
the ioctl() call with the FIOSETOWN or the SIOCSPGRP request,
or by the fcntl() call with the F_SETOWN command).
-
The accept_and_recv() function allows an application to reuse an existing socket
descriptor. If a socket descriptor is specified for the accept_socket_descriptor
parameter, it must not be bound or connected and it must have the same
address family and socket type as the listen_socket_descriptor. The socket descriptor
that is passed in for the accept_socket_descriptor parameter can be obtained by either
calling socket() or by specifying the SF_REUSE flag on the flags
parameter of the send_file() function.
If an application specifies a pointer to an unbound and unconnected socket
descriptor for the accept_socket_descriptor parameter that is the same address family
and socket type as the listen_socket_descriptor, the accept_and_recv() function will try to use
the accept_socket_descriptor for the incoming connection. If the accept_socket_descriptor 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 accept_socket_descriptor parameter may
not be the same value that was specified by the application when the
accept_and_recv() function was called.
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 accept_socket_descriptor parameter. If socket reuse is not supported and the
send_file() API is called with the flags parameter set to SF_REUSE, the
socket connection will be closed and the socket descriptor will be set to
-1 by the send_file() 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 accept_and_recv()
function as the accept_socket_descriptor parameter.
-
To take full advantage of the performance improvement offered by the
accept_and_recv() API, a multiple accept server model needs to be used by the
application. In this model the server will do a socket(), bind(), and
listen() as currently is done. The server will then give the listening
socket to multiple jobs or threads. Each job or thread will then call
accept_and_recv() using the same listening socket. When a connection request
comes in, only one of the jobs or threads would wake up.
- If a successful Rbind() 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.
Related Information