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();