Winsock2 API
The Windows Sockets API (Winsock) provides a C-style interface for network programming. Winsock 2 extends the original Winsock specification with new features and support for a wider range of network protocols and services.
This documentation provides an overview of common Winsock 2 functions, structures, and concepts. Understanding these elements is crucial for developing robust and efficient network applications on Windows.
Core Functions
WSAStartup
int WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);
Parameters
- wVersionRequired: [in] The highest version of the Winsock specification that the calling application can support.
- lpWSAData: [out] A pointer to a WSADATA structure that receives details about the Winsock implementation.
Return Value
If the function succeeds, the return value is 0, and the WSADATA structure pointed to by lpWSAData is filled with appropriate version and capabilities information. If the function fails, the return value is one of the Winsock error codes indicated by WSAGetLastError.
Remarks
An application must successfully call WSAStartup before calling any other Winsock functions. It is recommended that an application call WSAStartup with a version that is compatible with the Winsock DLL. For example, to request version 2.2, the application should set wVersionRequired to MAKEWORD(2, 2).
socket
SOCKET socket(int af, int type, int protocol);
Parameters
- af: [in] The address family. For the Internet Protocol version 4 (IPv4), set this to AF_INET. For the Internet Protocol version 6 (IPv6), set this to AF_INET6. For the NetBIOS, set this to AF_NETBIOS.
- type: [in] The socket type. Supported socket types are SOCK_STREAM (a connection-oriented socket type that provides reliable, in-order, two-way connection-based byte streams) or SOCK_DGRAM (a connectionless socket type that supports datagrams).
- protocol: [in] The protocol for the socket. The most common value for the IPPROTO parameter is IPPROTO_TCP or IPPROTO_UDP.
Return Value
If no error occurs, socket returns a descriptor for the newly created socket. Otherwise, it returns INVALID_SOCKET, and a specific error code can be retrieved by calling WSAGetLastError.
Remarks
The socket function creates a socket that is bound to a specific transport service provider. The application can use the returned socket descriptor in subsequent socket function calls.
bind
int bind(SOCKET s, const struct sockaddr FAR *name, int namelen);
Parameters
- s: [in] A descriptor identifying an unbound socket.
- name: [in] A pointer to the name to assign to the socket. This is a structure that specifies the address and port number for the socket.
- namelen: [in] The length, in bytes, of the structure specified by the name parameter.
Return Value
If no error occurs, bind returns zero. Otherwise, it returns a value of SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.
Remarks
The bind function associates a local name (address and port) with a socket. For a server application, you typically bind a socket to a specific local IP address (often the wildcard address INADDR_ANY to accept connections on any interface) and a specific port number.
connect
int connect(SOCKET s, const struct sockaddr FAR *name, int namelen);
Parameters
- s: [in] A descriptor identifying an unconnected socket.
- name: [in] A pointer to a structure containing the remote address and port to which to connect.
- namelen: [in] The length, in bytes, of the structure specified by the name parameter.
Return Value
If the connection is established immediately, connect returns zero. If the socket is nonblocking and the connection cannot be established immediately, connect returns SOCKET_ERROR and WSAGetLastError returns WSAEINPROGRESS. If the socket is blocking, the function will not return until the connection is established or an error occurs.
Remarks
The connect function establishes a connection to a specified remote socket. For connection-oriented protocols like TCP, this function is used by a client to initiate a connection to a server.
listen
int listen(SOCKET s, int backlog);
Parameters
- s: [in] A descriptor identifying an unbound socket that has been bound to an address.
- backlog: [in] The maximum number of pending connections that can be queued.
Return Value
If no error occurs, listen returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.
Remarks
The listen function places a socket in a state where it is listening for incoming connection requests. When a connection request arrives from a client, it is placed in a queue.
accept
SOCKET accept(SOCKET s, struct sockaddr FAR * addr, int FAR * addrlen);
Parameters
- s: [in] A descriptor that identifies a socket that is in a listening state.
- addr: [out, optional] An optional pointer to a buffer that receives the address of the remote party to which the socket is connected.
- addrlen: [in, out, optional] The size, in bytes, of the buffer pointed to by the addr parameter.
Return Value
If no error occurs, accept returns a descriptor for a newly created socket that is connected to a client that is ready to send and receive data. If the socket is nonblocking and no connections are ready to be accepted, accept returns SOCKET_ERROR and WSAGetLastError returns WSAEWOULDBLOCK.
Remarks
The accept function extracts the first connection available in the queue of pending connections on socket s, creates a new socket with the same properties of s, and assigns the remote client's address and port to the new socket. The newly created socket handles the actual communication with the remote client. The original socket s continues to listen for additional connections.
send
int send(SOCKET s, const char FAR * buf, int len, int flags);
Parameters
- s: [in] A descriptor identifying the socket.
- buf: [in] A pointer to a buffer containing the data to be sent.
- len: [in] The number of bytes to send from the buffer.
- flags: [in] Flags used to control data transmission.
Return Value
If no error occurs, send returns the total number of bytes sent. If the socket is nonblocking and cannot send data immediately, send returns SOCKET_ERROR and WSAGetLastError returns WSAEWOULDBLOCK. If the socket is blocking, the function will not return until data can be sent or an error occurs.
Remarks
The send function is used with connection-oriented sockets (for example, SOCK_STREAM) to transmit data.
recv
int recv(SOCKET s, char FAR * buf, int len, int flags);
Parameters
- s: [in] A descriptor identifying the socket.
- buf: [out] A pointer to a buffer that will receive the incoming data.
- len: [in] The maximum number of bytes to receive.
- flags: [in] Flags that specify the way to receive data.
Return Value
If no error occurs, recv returns the number of bytes received. If the calling process has no incoming messages available on the socket and the socket is nonblocking, recv returns SOCKET_ERROR and WSAGetLastError returns WSAEWOULDBLOCK. If the socket is blocking, the function will not return until a message is available or an error occurs.
If the remote party has shut down the connection gracefully, recv will return 0.
Remarks
The recv function is used with connection-oriented sockets (for example, SOCK_STREAM) to receive data.
closesocket
int closesocket(SOCKET s);
Parameters
- s: [in] A descriptor identifying the socket to be closed.
Return Value
If no error occurs, closesocket returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.
Remarks
The closesocket function closes an existing socket. Any attempt to use the socket after it is closed will fail.
getaddrinfo
INT getaddrinfo(PCSTR pNodeName, PCSTR pServiceName, const ADDRINFOA * pHints, PADDRINFOA * ppResult);
Parameters
- pNodeName: [in, optional] The hostname or IP address of the host.
- pServiceName: [in, optional] The port number or service name.
- pHints: [in, optional] A pointer to an ADDRINFO structure that specifies criteria for the caller to filter the server address list.
- ppResult: [out] A pointer to a linked list of ADDRINFO structures that contains response information about the host.
Return Value
If the function succeeds, the return value is 0. If the function fails, the return value is a non-zero error code from gai_strerror.
Remarks
The getaddrinfo function provides protocol-independent translation of hostnames and service names into a set of socket addresses that can be used with the socket APIs. This is the modern, preferred way to resolve network addresses compared to older functions like gethostbyname.
getnameinfo
INT getnameinfo(const SOCKADDR * pSockaddr, socklen_t SockaddrLength, PCHAR pNodeBuffer, SIZE_T NodeBufferSize, PCHAR pServiceBuffer, SIZE_T ServiceBufferSize, INT Flags);
Parameters
- pSockaddr: [in] A pointer to a buffer containing a socket address structure.
- SockaddrLength: [in] The length, in bytes, of the socket address structure.
- pNodeBuffer: [out, optional] A pointer to a buffer that receives the node name.
- NodeBufferSize: [in] The size, in bytes, of the buffer pointed to by pNodeBuffer.
- pServiceBuffer: [out, optional] A pointer to a buffer that receives the service name.
- ServiceBufferSize: [in] The size, in bytes, of the buffer pointed to by pServiceBuffer.
- Flags: [in] Flags that control the operation.
Return Value
If the function succeeds, the return value is 0. If the function fails, the return value is a non-zero error code.
Remarks
The getnameinfo function provides protocol-independent translation of a socket address structure into a host name and service name. It is the inverse operation of getaddrinfo.
select
int select(int nfds, fd_set FAR * readfds, fd_set FAR * writefds, fd_set FAR * exceptfds, const struct timeval FAR * timeout);
Parameters
- nfds: [in] The highest-numbered file descriptor in any of the sets, plus one.
- readfds: [in, out, optional] A pointer to a set of file descriptors to be checked for readiness for reading.
- writefds: [in, out, optional] A pointer to a set of file descriptors to be checked for readiness for writing.
- exceptfds: [in, out, optional] A pointer to a set of file descriptors to be checked for exceptional conditions.
- timeout: [in, out, optional] A pointer to a structure specifying the time interval that the function can block.
Return Value
If no error occurs, select returns the total number of file descriptors contained in the selected sets that are ready for reading, writing, or exceptional conditions. If the timeout interval elapses before any file descriptor is ready, it returns 0. If an error occurs, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.
Remarks
The select function determines the status of one or more file descriptors. It can be used to check if a socket is ready for reading, writing, or has an exceptional condition pending. This is useful for managing multiple sockets concurrently.
WSACleanup
int WSACleanup(void);
Parameters
None.
Return Value
If the function succeeds, the return value is 0. If the function fails, the return value is SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.
Remarks
The WSACleanup function terminates the use of the Winsock 2 DLL. It is called by a process or thread that has previously called WSAStartup. WSACleanup deallocates any resources that were allocated by the Winsock DLL.
Basic Example Snippets
Here are conceptual snippets demonstrating how to use some of these functions. For full, runnable examples, please refer to the official Microsoft documentation.
TCP Client Socket Creation and Connection
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
// Handle error
return 1;
}
// Create a SOCKET
SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
// Handle error
WSACleanup();
return 1;
}
// Prepare the sockaddr structure
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8080); // Example port
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Example IP
// Connect to the server
iResult = connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));
if (iResult == SOCKET_ERROR) {
// Handle error
closesocket(clientSocket);
WSACleanup();
return 1;
}
// Connection established, proceed with send/recv...
// Clean up
closesocket(clientSocket);
WSACleanup();
TCP Server Socket Listening
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
// Handle error
return 1;
}
// Create a SOCKET
SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listenSocket == INVALID_SOCKET) {
// Handle error
WSACleanup();
return 1;
}
// Prepare the sockaddr structure
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8080); // Example port
serverAddr.sin_addr.s_addr = INADDR_ANY; // Listen on all interfaces
// Bind the socket
iResult = bind(listenSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));
if (iResult == SOCKET_ERROR) {
// Handle error
closesocket(listenSocket);
WSACleanup();
return 1;
}
// Start listening for incoming connections
iResult = listen(listenSocket, SOMAXCONN); // SOMAXCONN is a system-defined backlog queue size
if (iResult == SOCKET_ERROR) {
// Handle error
closesocket(listenSocket);
WSACleanup();
return 1;
}
// Now accept incoming connections...
// SOCKET clientSocket = accept(listenSocket, NULL, NULL);
// ...
// Clean up
closesocket(listenSocket);
WSACleanup();