WSAAccept function (winsock2.h)
The WSAAccept function conditionally accepts a connection based on the return value of a condition function, provides quality of service flow specifications, and allows the transfer of connection data.
Syntax
SOCKET WSAAPI WSAAccept(
[in] SOCKET s,
[out] sockaddr *addr,
[in, out] LPINT addrlen,
[in] LPCONDITIONPROC lpfnCondition,
[in] DWORD_PTR dwCallbackData
);
Parameters
[in] s
A descriptor that identifies a socket that is listening for connections after a call to the listen function.
[out] addr
An optional pointer to an sockaddr structure that receives the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family established when the socket was created.
[in, out] addrlen
An optional pointer to an integer that contains the length of the sockaddr structure pointed to by the addr parameter, in bytes.
[in] lpfnCondition
The address of an optional, application-specified condition function that will make an accept/reject decision based on the caller information passed in as parameters, and optionally create or join a socket group by assigning an appropriate value to the result parameter g of this function. If this parameter is NULL, then no condition function is called.
[in] dwCallbackData
Callback data passed back to the application-specified condition function as the value of the dwCallbackData parameter passed to the condition function. This parameter is only applicable if the lpfnCondition parameter is not NULL. This parameter is not interpreted by Windows Sockets.
Return value
If no error occurs, WSAAccept returns a value of type SOCKET that is a descriptor for the accepted socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling WSAGetLastError.
The integer referred to by addrlen initially contains the amount of space pointed to by addr. On return it will contain the actual length in bytes of the address returned.
Error code | Meaning |
---|---|
An attempt was made to access a socket in a way forbidden by its access permissions. This error is returned if the connection request that was offered has timed out or been withdrawn. | |
No connection could be made because the target machine actively refused it. This error is returned if the connection request was forcefully rejected as indicated in the return value of the condition function (CF_REJECT). | |
An existing connection was forcibly closed by the remote host. This error is returned of an incoming connection was indicated, but was subsequently terminated by the remote peer prior to accepting the call. | |
The system detected an invalid pointer address in attempting to use a pointer argument in a call. This error is returned of the addrlen parameter is too small or the addr or lpfnCondition is not part of the user address space. | |
A blocking operation was interrupted by a call to WSACancelBlockingCall. This error is returned if a blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall. | |
A blocking operation is currently executing. This error is returned if a blocking Windows Sockets 1.1 call is in progress. | |
An invalid argument was supplied. This error is returned if listen was not invoked prior to WSAAccept, the return value of the condition function is not a valid one, or any case where the specified socket is in an invalid state. | |
Too many open sockets. This error is returned if the queue is nonempty upon entry to WSAAccept and there are no socket descriptors available. | |
A socket operation encountered a dead network. This error is returned if the network subsystem has failed. | |
An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full. This error is returned if no buffer space is available. | |
An operation was attempted on something that is not a socket. This error is returned if the socket descriptor passed in the s parameter is not a socket. | |
The protocol family has not been configured into the system or no implementation for it exists. This error is returned if the referenced socket is not a type that supports connection-oriented service. | |
A non-blocking socket operation could not be completed immediately. This error is returned if the socket is marked as nonblocking and no connections are present to be accepted. | |
Either the application has not called WSAStartup, or WSAStartup failed. This error is returned of a successful call to the WSAStartup function dit not occur before using this function. | |
This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server. This error is returned if the acceptance of the connection request was deferred as indicated in the return value of the condition function (CF_DEFER). |
Remarks
The WSAAccept function extracts the first connection on the queue of pending connections on socket s, and checks it against the condition function, provided the condition function is specified (that is, not NULL). If the condition function returns CF_ACCEPT, WSAAccept creates a new socket. The newly created socket has the same properties as socket s including asynchronous events registered with WSAAsyncSelect or with WSAEventSelect. If the condition function returns CF_REJECT, WSAAccept rejects the connection request. The condition function runs in the same thread as this function does, and should return as soon as possible. If the decision cannot be made immediately, the condition function should return CF_DEFER to indicate that no decision has been made, and no action about this connection request should be taken by the service provider. When the application is ready to take action on the connection request, it will invoke WSAAccept again and return either CF_ACCEPT or CF_REJECT as a return value from the condition function.
A socket in default mode (blocking) will block until a connection is present when an application calls WSAAccept and no connections are pending on the queue.
A socket in nonblocking mode (blocking) fails with the error WSAEWOULDBLOCK when an application calls WSAAccept and no connections are pending on the queue. After WSAAccept succeeds and returns a new socket handle, the accepted socket cannot be used to accept any more connections. The original socket remains open and listens for new connection requests.
The addr parameter is a result parameter that is filled in with the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family in which the communication is occurring. The addrlen is a value-result parameter; it should initially contain the amount of space pointed to by addr. On return, it will contain the actual length (in bytes) of the address returned. This call is used with connection-oriented socket types such as SOCK_STREAM. If addr and/or addrlen are equal to NULL, then no information about the remote address of the accepted socket is returned. Otherwise, these two parameters will be filled in if the connection is successfully accepted.
A prototype of the condition function is defined in the Winsock2.h
header file as the LPCONDITIONPROC, as follows.
int CALLBACK
ConditionFunc(
IN LPWSABUF lpCallerId,
IN LPWSABUF lpCallerData,
IN OUT LPQOS lpSQOS,
IN OUT LPQOS lpGQOS,
IN LPWSABUF lpCalleeId,
IN LPWSABUF lpCalleeData,
OUT GROUP FAR * g,
IN DWORD_PTR dwCallbackData
);
The ConditionFunc is a placeholder for the application-specified callback function. The actual condition function must reside in a DLL or application module. It is exported in the module definition file.
The lpCallerId parameter points to a WSABUF structure that contains the address of the connecting entity, where its len parameter is the length of the buffer in bytes, and its buf parameter is a pointer to the buffer. The lpCallerData is a value parameter that contains any user data. The information in these parameters is sent along with the connection request. If no caller identification or caller data is available, the corresponding parameters will be NULL. Many network protocols do not support connect-time caller data. Most conventional network protocols can be expected to support caller identifier information at connection-request time. The buf portion of the WSABUF pointed to by lpCallerId points to a sockaddr. The sockaddr structure is interpreted according to its address family (typically by casting the sockaddr to some type specific to the address family).
The lpSQOS parameter references the FLOWSPEC structures for socket s specified by the caller, one for each direction, followed by any additional provider-specific parameters. The sending or receiving flow specification values will be ignored as appropriate for any unidirectional sockets. A NULL value indicates that there is no caller-supplied quality of service and that no negotiation is possible. A non-NULL lpSQOS pointer indicates that a quality of service negotiation is to occur or that the provider is prepared to accept the quality of service request without negotiation.
The lpGQOS parameter is reserved, and should be NULL. (reserved for future use with socket groups) references the FLOWSPEC structure for the socket group the caller is to create, one for each direction, followed by any additional provider-specific parameters. A NULL value for lpGQOS indicates no caller-specified group quality of service. Quality of service information can be returned if negotiation is to occur.
The lpCalleeId is a parameter that contains the local address of the connected entity. The buf portion of the WSABUF pointed to by lpCalleeId points to a sockaddr structure. The sockaddr structure is interpreted according to its address family (typically by casting the sockaddr to some type specific to the address family such as struct sockaddr_in).
The lpCalleeData is a result parameter used by the condition function to supply user data back to the connecting entity. The lpCalleeData->len initially contains the length of the buffer allocated by the service provider and pointed to by lpCalleeData->buf. A value of zero means passing user data back to the caller is not supported. The condition function should copy up to lpCalleeData->len bytes of data into lpCalleeData->buf, and then update lpCalleeData->len to indicate the actual number of bytes transferred. If no user data is to be passed back to the caller, the condition function should set lpCalleeData->len to zero. The format of all address and user data is specific to the address family to which the socket belongs.
The g parameter is assigned within the condition function to indicate any of the following actions:
- If g is an existing socket group identifier, add s to this group, provided all the requirements set by this group are met.
- If g = SG_UNCONSTRAINED_GROUP, create an unconstrained socket group and have s as the first member.
- If g = SG_CONSTRAINED_GROUP, create a constrained socket group and have s as the first member.
- If g = zero, no group operation is performed.
The dwCallbackData parameter value passed to the condition function is the value passed as the dwCallbackData parameter in the original WSAAccept call. This value is interpreted only by the Windows Socket version 2 client. This allows a client to pass some context information from the WSAAccept call site through to the condition function. This also provides the condition function with any additional information required to determine whether to accept the connection or not. A typical usage is to pass a (suitably cast) pointer to a data structure containing references to application-defined objects with which this socket is associated.
Example Code
The following example demonstrates the use of the WSAAccept function.#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
/* Define an example conditional function that depends on the pQos field */
int CALLBACK ConditionAcceptFunc(
LPWSABUF lpCallerId,
LPWSABUF lpCallerData,
LPQOS pQos,
LPQOS lpGQOS,
LPWSABUF lpCalleeId,
LPWSABUF lpCalleeData,
GROUP FAR * g,
DWORD_PTR dwCallbackData
)
{
if (pQos != NULL) {
RtlZeroMemory(pQos, sizeof(QOS));
return CF_ACCEPT;
} else
return CF_REJECT;
}
int main() {
/* Declare and initialize variables */
WSADATA wsaData;
SOCKET ListenSocket, AcceptSocket;
struct sockaddr_in saClient;
int iClientSize = sizeof(saClient);
u_short port = 27015;
char* ip;
sockaddr_in service;
int error;
/* Initialize Winsock */
error = WSAStartup(MAKEWORD(2,2), &wsaData);
if (error) {
printf("WSAStartup() failed with error: %d\n", error);
return 1;
}
/* Create a TCP listening socket */
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
printf("socket() failed with error: %d\n", WSAGetLastError() );
WSACleanup();
return 1;
}
/*-----------------------------------------
* Set up the sock addr structure that the listening socket
* will be bound to. In this case, the structure holds the
* local IP address and the port specified. */
service.sin_family = AF_INET;
service.sin_port = htons(port);
hostent* thisHost;
thisHost = gethostbyname("");
ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);
service.sin_addr.s_addr = inet_addr(ip);
/*-----------------------------------------
* Bind the listening socket to the IP address.
* and port number specified by the sockaddr structure. */
error = bind(ListenSocket, (SOCKADDR *) &service, sizeof(SOCKADDR));
if (error == SOCKET_ERROR) {
printf("bind() failed with error: %d\n", WSAGetLastError() );
closesocket(ListenSocket);
WSACleanup();
return 1;
}
/* Make the socket listen for incoming connection requests */
error = listen(ListenSocket, 1);
if (error == SOCKET_ERROR) {
printf("listen() failed with error: %d\n", WSAGetLastError() );
closesocket(ListenSocket);
WSACleanup();
return 1;
}
printf("Listening...\n");
/*-----------------------------------------
* Accept an incoming connection request on the
* listening socket and transfer control to the
* accepting socket. */
AcceptSocket = WSAAccept(ListenSocket, (SOCKADDR*) &saClient, &iClientSize,
&ConditionAcceptFunc, NULL);
/* Now do some work with the AcceptSocket
* At this point, the application could
* handle data transfer on the socket, or other socket
* functionality.*/
/* Then clean up and quit */
closesocket(AcceptSocket);
closesocket(ListenSocket);
WSACleanup();
return 0;
}
Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later.
Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows Server 2012 R2, and later.
Requirements
Requirement | Value |
---|---|
Minimum supported client | Windows 8.1, Windows Vista [desktop apps | UWP apps] |
Minimum supported server | Windows Server 2003 [desktop apps | UWP apps] |
Target Platform | Windows |
Header | winsock2.h |
Library | Ws2_32.lib |
DLL | Ws2_32.dll |