accept_and_recv()--Wait for Connection Request and Receive the First Message That Was Sent


  BSD 4.3 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)

  Service Program Name: QSOSRV1

  Default Public Authority: *USE

  Threadsafe: Yes



  UNIX 98 Compatible Syntax
  #define _XOPEN_SOURCE 520
  #include <sys/socket.h>

  int accept_and_recv(int listen_socket_descriptor,
                      int *accept_socket_descriptor,
                      struct sockaddr *remote_address,
                      socklen_t *remote_address_length,
                      struct sockaddr *local_address,
                      socklen_t *local_address_length,
                      void *buffer,
                      size_t buffer_length)

  Service Program Name: QSOSRV1

  Default Public Authority: *USE

  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 or AF_INET6 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().

There are two versions of the API, as shown above. The base IBM® i 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 _XOPEN_SOURCE macro.


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>.

The BSD 4.3 structure is:

      struct sockaddr {
         u_short sa_family;
         char    sa_data[14];
      };

The BSD 4.4/UNIX 98 compatible structure is:

      typedef uchar   sa_family_t;

      struct sockaddr {
         uint8_t     sa_len;
         sa_family_t sa_family;
         char        sa_data[14];
      };

The BSD 4.4 sa_len field is the length of the address. 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.

Note: See the usage notes about using different address families with sockaddr_storage.

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>.

The BSD 4.3 structure is:

      struct sockaddr {
         u_short sa_family;
         char    sa_data[14];
      };

The BSD 4.4/UNIX 98 compatible structure is:

      typedef uchar   sa_family_t;

      struct sockaddr {
         uint8_t     sa_len;
         sa_family_t sa_family;
         char        sa_data[14];
      };

The BSD 4.4 sa_len field is the length of the address. 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.

Note: See the usage notes about using different address families with sockaddr_storage.

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:


Error Conditions

When accept_and_recv() fails, errno can be set to one of the following:



Error Messages



Usage Notes

  1. The accept_and_recv() 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 listen_socket_descriptor does not have the correct address family and socket type, -1 is returned and the errno value is set to EOPNOTSUPP.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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).


  7. 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.

  8. The structure sockaddr 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 sockaddr_storage. This structure is large enough and aligned for any protocol-specific structure. It may then be cast as sockaddr structure for use on the APIs. The ss_family field of the sockaddr_storage will always align with the family field of any protocol-specific structure.

    The BSD 4.3 structure is:

     #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];
     };
    

    The BSD 4.4/UNIX 98 compatible structure is:

     #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];
     };
    
  9. 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.

  10. 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.
  11. 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 accept_and_recv() API is mapped to qso_accept_and_recv98().
  12. A user exit point, QIBM_QSO_ACCEPT, exists to optionally accept or reject incoming connections being accepted based on the return code from the registered user exit program. For more information refer to Sockets accept() API Exit Program.

Related Information



API introduced: V4R3

[ Back to top | UNIX-Type APIs | APIs by category ]