Accepting Connections
This document describes how to use the accept()
function in Winsock to accept incoming connection requests on a listening socket.
The accept()
Function
The accept()
function is used to retrieve a connection request on a socket that is in a listening state. When a connection is available, accept()
creates a new socket that is connected to the client and returns a handle to this new socket.
Syntax
SOCKET accept(
[in] SOCKET ListenSocket,
[out] sockaddr *Addr,
[in, out] int *AddrLen
);
Parameters
-
ListenSocket
: [in] A descriptor identifying a socket that is bound to a specific transport address and is listening for connection attempts. -
Addr
: [out] An optional pointer to a buffer that will receive the address structure of the connecting entity. -
AddrLen
: [in, out] A pointer to an integer value that specifies the size, in bytes, of the buffer pointed to by theAddr
parameter.
Return Value
If no error occurs, accept()
returns a descriptor for a newly created socket that is connected to (a peer)
. This returned socket is ready for sending and receiving data. If an error occurs, the function returns INVALID_SOCKET
, and a specific error code can be retrieved by calling WSAGetLastError()
.
Steps to Accept a Connection
- Create a Listening Socket: Use
socket()
to create a TCP socket. - Bind the Socket: Use
bind()
to associate the socket with a local address and port. - Listen for Connections: Use
listen()
to put the socket into a listening state. - Accept an Incoming Connection: Call
accept()
. This call will block until a client connection is established. - Communicate with the Client: Use the new socket returned by
accept()
to send and receive data with the connected client using functions likesend()
andrecv()
. - Close the Client Socket: When communication is complete, close the client socket using
closesocket()
.
Example Usage (Conceptual)
The following C++ snippet illustrates the basic flow of using accept()
:
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
// ... (Initialization code for Winsock)
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET) {
// Handle error
}
SOCKADDR_IN serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8080); // Example port
serverAddr.sin_addr.s_addr = INADDR_ANY;
if (bind(serverSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
// Handle error
}
if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) {
// Handle error
}
SOCKADDR_IN clientAddr;
int clientAddrSize = sizeof(clientAddr);
SOCKET clientSocket = accept(serverSocket, (SOCKADDR*)&clientAddr, &clientAddrSize);
if (clientSocket == INVALID_SOCKET) {
// Handle error
} else {
// Successfully accepted a connection
// Communicate with clientSocket here
closesocket(clientSocket); // Close the client socket when done
}
closesocket(serverSocket); // Close the listening socket
// ... (Cleanup code for Winsock)
Important Considerations
- Blocking vs. Non-Blocking: By default,
accept()
is a blocking function. If you need non-blocking behavior, you must configure the listening socket accordingly usingioctlsocket()
. - Error Handling: Always check the return value of
accept()
forINVALID_SOCKET
and retrieve the specific error code usingWSAGetLastError()
for robust error handling. - Thread Safety: In a multi-threaded server application, ensure proper synchronization mechanisms are in place if multiple threads might call
accept()
on the same listening socket (though typically, a single thread handles listening and accepting).