Colin Sutter
Colin Sutter

Reputation: 60

c++ Windows 10 Get an Ip for a connected client

I have set up a working WinSock2 Socket were a client can connect, how can I get the IP address of a connected client.

Upvotes: 0

Views: 310

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595320

The client's IP address is reported by accept() when the client is first accepted. It can also be queried from the client SOCKET at any time using getpeername(). Both functions fill in a sockaddr_... struct that you must allocate and pass in, based on the address type assigned when you created the server socket using socket():

  • If AF_INET, provide a sockaddr_in struct:
sockaddr_in clientAddr;
int clientAddrSize = sizeof(clientAddr);
SOCKET client = accept(server, (sockaddr*)&client_addr, &clientAddrSize);
if (client != INVALID_SOCKET)
{
    // use client_addr.sin_addr as needed...
    ...
    clientAddrSize = sizeof(clientAddr);
    if (getpeername(client, (sockaddr*)&client_addr, &clientAddrSize) == 0)
    {
        // use client_addr.sin_addr as needed...
    }
    ...
    closesocket(client);
}
  • If AF_INET6 with IPV6_V6ONLY enabled, provide a sockaddr_in6 struct:
sockaddr_in6 clientAddr;
int clientAddrSize = sizeof(clientAddr);
SOCKET client = accept(server, (sockaddr*)&client_addr, &clientAddrSize);
if (client != INVALID_SOCKET)
{
    // use client_addr.sin6_addr as needed...
    ...
    clientAddrSize = sizeof(clientAddr);
    if (getpeername(client, (sockaddr*)&client_addr, &clientAddrSize) == 0)
    {
        // use client_addr.sin6_addr as needed...
    }
    ...
    closesocket(client);
}
  • If AF_INET6 with IPV6_V6ONLY disabled, provide a sockaddr_storage struct, and then look at its ss_family field to know whether to cast the sockaddr_storage data to sockaddr_in or sockaddr_in6:
sockaddr_storage clientAddr;
sockaddr_in *clientAddr4;
sockaddr_in6 *clientAddr6;
int clientAddrSize = sizeof(clientAddr);
SOCKET client = accept(server, (sockaddr*)&client_addr, &clientAddrSize);
if (client != INVALID_SOCKET)
{
    switch (client_addr.ss_family)
    {
        case AF_INET:
            clientAddr4 = use reinterpret_cast<sockaddr_in*>(&client_addr);
            // use clientAddr4->sin_addr as needed...
            break;
        case AF_INET6:
            clientAddr6 = use reinterpret_cast<sockaddr_in6*>(&client_addr);
            // use clientAddr6->sin6_addr as needed...
            break;
    }
    ...
    clientAddrSize = sizeof(clientAddr);
    if (getpeername(client, (sockaddr*)&client_addr, &clientAddrSize) == 0)
    {
        switch (client_addr.ss_family)
        {
            case AF_INET:
                clientAddr4 = use reinterpret_cast<sockaddr_in*>(&client_addr);
                // use clientAddr4->sin_addr as needed...
                break;
            case AF_INET6:
                clientAddr6 = use reinterpret_cast<sockaddr_in6*>(&client_addr);
                // use clientAddr6->sin6_addr as needed...
                break;
        }
    }
    ...
    closesocket(client);
}

Upvotes: 1

Related Questions