accept_and_recv() — Accept connection and receive first message
Standards
Standards / Extensions | C or C++ | Dependencies |
---|---|---|
z/OS® UNIX | both |
Format
#define _OPEN_SYS_SOCK_EXT2
#include <sys/socket.h>
int accept_and_recv(int socket, int *accept_socket,
struct sockaddr *remote_address,
socklen_t *remote_address_len,
struct sockaddr *local_address,
socklen_t *local_address_len,
void *buffer, size_t buffer_len);
General description
The accept_and_recv() function extracts the first connection on the queue of pending connections. It either reuses the specified socket (if *accept_socket is not -1) or creates a new socket with the same socket type, protocol, and address family as the listening socket (if *accept_socket is -1). It then returns the first block of data sent by the peer and returns the local and remote socket addresses associated with the connection.
- Parameter
- Description
- socket
- Specifies a socket that was created with socket(), has been bound to an address with bind(), and has issued a successful call to listen().
- accept_socket
- Pointer to an
int
which specifies the socket on which to accept the incoming connection. The socket must not be bound or connected. Use of this parameter lets the application reuse the accepting socket. It is possible that the system may choose to reuse a different socket than the one the application specified by this argument. In this case, the system will set *accept_socket to the socket actually reused.A value of -1 for *accept_socket indicates that the accepting socket should be assigned by the system and returned to the application in this parameter. It is recommended that a value of -1 be used on the first call to accept_and_recv(). For more details, see Usage notes.
- remote_address
- Either a NULL pointer or a pointer to a
sockaddr
structure where the address of the connecting socket will be returned. - remote_address_len
- Points to a
socklen_t
. On input, this specifies the length of the suppliedsockaddr
structure. On output, this contains the length of the stored address. - local_address
- Either a NULL pointer or a pointer to a
sockaddr
structure where the address of the local socket will be returned. - local_address_len
- Points to a
socklen_t
. On input, this specifies the length of the suppliedsockaddr
structure. On output, this contains the length of the stored address. - buffer
- Either a NULL pointer, or a pointer to a buffer where the message should be stored. If this is a NULL pointer, no receive is performed, and accept_and_recv() completes when the incoming connection is received.
- buffer_len
- Specifies the length in bytes of the buffer pointed to by the buffer argument.
If *accept_socket is not -1, the incoming connection will be accepted on the socket specified by *accept_socket. The system may choose to reuse a different socket. If it does, the system will change *accept_socket to reflect the socket actually used.
If remote_address is
not a NULL pointer, the address of the peer for the accepted connection
is stored in the sockaddr
structure pointed to by remote_address,
and the length of this address is stored in the object pointed to
by remote_address_len. If the actual length
of the address is greater than the length of the supplied socket address
structure, the stored address will be truncated.
If local_address is
not a NULL pointer, the address of the local socket associated with
this connection is stored in the sockaddr
structure
pointed to by local_address, and the length
of this address is stored in the object pointed to by local_address_len.
If the actual length of the address is greater than the length of
the supplied socket address structure, the stored address will be
truncated.
Nonblocking mode is not supported for this function.
If O_NONBLOCK
is set on the socket file descriptor,
the function will return with -1 and errno will be set to EOPNOTSUPP
.
If the listen queue is empty of connection requests, accept_and_recv() will not return until an incoming connection is received.
If buffer is not NULL, accept_and_recv will not return until the first block of data on the connection has been received, otherwise accept_and_recv() returns 0 after the connection is established.
Usage notes
- On the first call to accept_and_recv(), it is recommended that
the application set the socket pointed to by accept_socket to
-1. This will cause the system to assign the accepting socket. The
application then passes the assigned value into the next call to accept_and_recv()
(by setting accept_socket = socket_ptr).
To take full advantage of the performance improvements offered by the accept_and_recv() function, a process/thread model different from the one where a parent accepts in a loop and spins off child process threads is needed. The parent/process thread is eliminated. Multiple worker processes/threads are created, and each worker process/thread then executes the accept_and_recv() function in a loop. The performance benefits of accept_and_recv() include fewer buffer copies, recycled sockets, and optimal scheduling.
Returned value
If successful, accept_and_recv() returns the number of bytes (zero or more) stored in the buffer pointed to by the buffer argument. Zero can be returned when buffer is NULL or when the client closes the socket without sending any data.
A partial success is achieved with *accept_socket being assigned, a return value of -1 and errno set to one of the following values:
- Error Code
- Description
- EINTRNODATA
- The accept_and_recv() function was interrupted by a signal that was caught after a valid connection was established, but before the first block of data arrived.
- EWOULDBLOCK
- A new connection was established, but the SO_RCVTIMEO timeout value was reached before data was available.
If unsuccessful, accept_and_recv() sets *accepted_socket to -1, returns -1 and sets errno to one of the following values:
- Error Code
- Description
- EBADF
- One of two errors occurred:
- socket is not a valid descriptor.
- accept_socket does not point to a valid descriptor.
- ECONNABORTED
- A connection has been aborted.
- ECONNRESET
- A connection was forcibly closed by a peer.
- EFAULT
- The data buffer pointed to by accept_socket, remote_address, remote_address_len, local_address, local_address_len, or buffer was not valid.
- EINTR
- The accept_and_recv() function was interrupted by a signal that was caught before a valid connection was established.
- EINVAL
- The socket is not accepting connections.
- EIO
- An I/O error occurred.
- EISCONN
- The accept_socket is either bound or connected already.
- EMFILE
OPEN_MAX
descriptors are already open in the calling process.- ENOBUFS
- No buffer space is available.
- ENOMEM
- There was insufficient memory available to complete the operation.
- ENOREUSE
- Socket reuse is not supported.
- ENOSR
- There were insufficient STREAMS resources available for the operation to complete.
- ENOTSOCK
- The socket argument does not refer to a socket, or accept_socket does not point to a socket.
- EOPNOTSUPP
- One of errors occurred:
- The type of the socket does not support accepting connections.
O_NONBLOCK
is set for the socket and nonblocking is not supported for this function.