I/O Control Operations (Winsock)

This section describes the I/O control (IOCTL) operations supported by Winsock. These operations allow applications to control the behavior of network sockets beyond the standard read and write operations.

Overview

Winsock supports a variety of IOCTLs that can be performed using the ioctlsocket function. These controls range from retrieving network interface information to setting socket options that are not exposed through standard setsockopt calls.

Important: Not all IOCTLs are supported by every Winsock implementation or transport protocol. Always check the documentation for the specific IOCTL and the expected behavior on your target platform.

Common IOCTL Codes

The following are some of the commonly used IOCTL codes for Winsock:

  • SIO_GET_EXTENSION_FUNCTION_POINTER: Retrieves a pointer to a Winsock extension function.
  • SIO_GET_BROADCAST_ERROR: Retrieves information about a broadcast error.
  • SIO_ADDRESS_LIST_FROM_NAME: Retrieves a list of network addresses for a given name.
  • SIO_ADDRESS_LIST_QUERY: Retrieves a list of network addresses for the local host.
  • SIO_GET_REMOTE_ADDRESS: Retrieves the remote address of a connected socket.
  • SIO_GET_LOCAL_ADDRESS: Retrieves the local address of a socket.
  • SIO_KEEPALIVE_VALS: Sets or retrieves Keep-Alive parameter values.
  • SIO_RCVALL: Enables or disables raw socket receive mode. (Deprecated)
  • SIO_UDP_CONNRESET: Enables or disables the UDP connection reset behavior.
  • SIO_SET_LINK: Sets the link interface for a socket. (Specific to certain providers)

Using ioctlsocket

The ioctlsocket function is used to perform these operations. Its signature is as follows:

int ioctlsocket(SOCKET s, long cmd, u_long *argp);
  • s: A descriptor identifying a socket.
  • cmd: The IOCTL code to perform.
  • argp: A pointer to the buffer that contains any data required for the operation, or where the results of the operation will be stored. The type and meaning of this argument depend on the specific IOCTL code.

Example: Retrieving Remote Address

The following C++ snippet demonstrates how to use ioctlsocket to get the remote address of a connected socket:


#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>

#pragma comment(lib, "Ws2_32.lib")

int main() {
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "WSAStartup failed." << std::endl;
        return 1;
    }

    SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "socket creation failed: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return 1;
    }

    // Assume clientSocket is connected to a server at this point...
    // For demonstration purposes, we'll just show the ioctl call.

    sockaddr_in remoteAddr;
    int addrLen = sizeof(remoteAddr);
    u_long argp = (u_long)&remoteAddr; // Cast to u_long* as required by ioctlsocket

    if (ioctlsocket(clientSocket, SIO_GET_REMOTE_ADDRESS, &argp) != SOCKET_ERROR) {
        // Successfully retrieved remote address
        char ipStr[INET_ADDRSTRLEN];
        InetNtop(AF_INET, &remoteAddr.sin_addr, ipStr, INET_ADDRSTRLEN);
        std::cout << "Remote IP: " << ipStr << std::endl;
        std::cout << "Remote Port: " << ntohs(remoteAddr.sin_port) << std::endl;
    } else {
        std::cerr << "SIO_GET_REMOTE_ADDRESS failed: " << WSAGetLastError() << std::endl;
    }

    closesocket(clientSocket);
    WSACleanup();
    return 0;
}
                
Note: The argument type for ioctlsocket (u_long*) is a legacy type. In modern C++, you might need to cast your pointer accordingly. The actual data buffer type depends on the IOCTL. For SIO_GET_REMOTE_ADDRESS, it's a pointer to a sockaddr_in structure.

See Also