AcceptEx
Notice This function
is a Microsoft-specific extension to the Windows Sockets specification. For
more information, see Microsoft Extensions and Windows Sockets 2 .
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);
}