AcceptEx  R3JUIO

Notice  This function is a Microsoft-specific extension to the Windows Sockets specification. For more information, see Microsoft Extensions and Windows Sockets 2D_9F.Q.

 

The Windows Sockets AcceptEx function accepts a new connection, returns the local and remote address, and receives the first block of data sent by the client application.

BOOL AcceptEx (

    SOCKET sListenSocket,

 

    SOCKET sAcceptSocket,

 

    PVOID lpOutputBuffer,

 

    DWORD dwReceiveDataLength,

 

    DWORD dwLocalAddressLength,

 

    DWORD dwRemoteAddressLength,

 

    LPDWORD lpdwBytesReceived,

 

    LPOVERLAPPED lpOverlapped

 

   );

 

 

Parameters

sListenSocket

[in] A descriptor identifying a socket that has already been called with the listen function. A server application waits for attempts to connect on this socket.

sAcceptSocket

[in] A descriptor identifying a socket on which to accept an incoming connection. This socket must not be bound or connected.

lpOutputBuffer

[in] A pointer to a buffer that receives the first block of data sent on a new connection, the local address of the server, and the remote address of the client. The receive data is written to the first part of the buffer starting at offset zero, while the addresses are written to the latter part of the buffer. This parameter must be specified.

dwReceiveDataLength

[in] The number of bytes in the buffer that will be used for receiving data. If this parameter is specified as zero, then no receive operation is performed in conjunction with accepting the connection. Instead, the AcceptEx function completes as soon as a connection arrives without waiting for any data.

dwLocalAddressLength

[in] The number of bytes reserved for the local address information. This must be at least 16 bytes more than the maximum address length for the transport protocol in use.

dwRemoteAddressLength

[in] The number of bytes reserved for the remote address information. This must be at least 16 bytes more than the maximum address length for the transport protocol in use.

lpdwBytesReceived

[out] A pointer to a DWORD that receives the count of bytes received. This is set only if the operation completes synchronously. If it returns ERROR_IO_PENDING and is completed later, then this DWORD is never set and you must obtain the number of bytes read from the completion notification mechanism.

lpOverlapped

[in] An OVERLAPPED structure that is used to process the request. This parameter must be specified; it cannot be NULL.

 

Return Values

If no error occurs, the AcceptEx function was successfully completed and a value of TRUE is returned. If the function was unsuccesful, the AcceptEx function returns FALSE. The GetLastError function can then be called to return extended error information. If GetLastError returns ERROR_IO_PENDING, then the operation was successfully initiated and is still in progress.

Remarks

The AcceptEx function combines several socket functions into a single API/kernel transition. The AcceptEx function, when successful, performs three tasks: a new connection is accepted, both the local and remote addresses for the connection are returned, and the first block of data sent by the remote is received. A program will make a connection to a socket more quickly using the AcceptEx function instead of the Accept function.

A single output buffer receives the data, the local socket address (the server), and the remote socket address (the client). Using a single buffer improves performance, but the GetAcceptExSockaddrs function must be called to parse the buffer into its three distinct parts.

Because the addresses are written in an internal format, the buffer size for the local and remote address must be 16 bytes more than the size of the SOCKADDR structure for the transport protocol in use. For example, the size of a SOCKADDR_IN   the address structure for TCP/IP   is 16 bytes, so specify a buffer size of at least 32 bytes for the local and remote addresses.

The AcceptEx function uses overlapped I/O, unlike the Windows Sockets 1.1 accept function. If your application uses the AcceptEx function, it can service a large number of clients with a relatively small number of threads.

As with all overlapped Win32 functions, either Win32 events or completion ports can be used as a completion notification mechanism.

Another key difference between the AcceptEx function and the Windows Sockets 1.1 accept function is that the AcceptEx function requires the caller to already have two sockets: one that specifies the socket on which to listen and one that specifies the socket on which to accept the connection. The sAcceptSocket parameter must be an open socket that is neither bound nor connected.

The lpNumberOfBytesTransferred parameter of the GetQueuedCompletionStatus function or the GetOverlappedResult function indicates the number of bytes received in the request.

When this operation is successfully completed, sAcceptHandle can be passed only to the following functions:

ReadFile

WriteFile

send

recv

TransmitFile

closesocket

 

 

Note  If you have called the TransmitFile function with both the TF_DISCONNECT and TF_REUSE_SOCKET flags, the specified socket has been returned to a state in which it is neither bound nor connected. You can then pass the handle of the socket to the AcceptEx function in the sAcceptSocket parameter.

 

In order to use sAcceptHandle with other Window Sockets 1.1 functions, call the setsockopt function with the SO_UPDATE_ACCEPT_CONTEXT option. This option initializes the socket so that other Windows Sockets routines to access the socket correctly.

When the AcceptEx function returns, sAcceptSocket is in the default state for a connected socket. The socket associated with the sAcceptSocket parameter does not inherit the properties of the socket associated with sListenSocket parameter until SO_UPDATE_ACCEPT_CONTEXT is set on the socket. Use the setsockopt function to set the SO_UPDATE_ACCEPT_CONTEXT option, specifying sAcceptSocket as the socket handle and sListenSocket as the option value.

For example:

err = setsockopt( sAcceptSocket,

    SOL_SOCKET,

    SO_UPDATE_ACCEPT_CONTEXT,

    (char *)&sListenSocket,

    sizeof(sListenSocket) );

 

You can use the getsockopt function with the SO_CONNECT_TIME option to check whether a connection has been accepted. If it has been accepted, you can determine how long the connection has been established. The return value is the number of seconds that the socket has been connected. If the socket is not connected, the getsockopt returns 0xFFFFFFFF. Checking a connection like this is necessary in order to check for connections that have been established for awhile, but no data has been received. You can then kill those connections.

For example:

INT seconds;

INT bytes = sizeof(seconds);

 

err = getsockopt( sAcceptSocket, SOL_SOCKET, SO_CONNECT_TIME,

                      (char *)&seconds, (PINT)&bytes );

if ( err != NO_ERROR ) { 

    printf( "getsockopt(SO_CONNECT_TIME) failed: %ld\n", WSAGetLastError( ) );

    exit(1);

}