Reputation: 60
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
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()
:
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);
}
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);
}
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