c++ Windows 10 为已连接的客户端获取 Ip
c++ Windows 10 Get an Ip for a connected client
我已经设置了一个客户端可以连接的工作 WinSock2 套接字,我怎样才能获得连接的客户端的 IP 地址。
客户端的IP地址由accept()
when the client is first accepted. It can also be queried from the client SOCKET
at any time using getpeername()
报告。这两个函数都填充了一个 sockaddr_...
结构,您必须根据使用 socket()
:
创建服务器套接字时分配的地址类型分配并传入该结构
- 如果
AF_INET
,提供一个sockaddr_in
结构:
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
启用 IPV6_V6ONLY
,请提供 sockaddr_in6
结构:
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
禁用 IPV6_V6ONLY
,提供一个 sockaddr_storage
结构,然后查看其 ss_family
字段以了解是否转换 sockaddr_storage
数据到 sockaddr_in
或 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);
}
我已经设置了一个客户端可以连接的工作 WinSock2 套接字,我怎样才能获得连接的客户端的 IP 地址。
客户端的IP地址由accept()
when the client is first accepted. It can also be queried from the client SOCKET
at any time using getpeername()
报告。这两个函数都填充了一个 sockaddr_...
结构,您必须根据使用 socket()
:
- 如果
AF_INET
,提供一个sockaddr_in
结构:
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
启用IPV6_V6ONLY
,请提供sockaddr_in6
结构:
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
禁用IPV6_V6ONLY
,提供一个sockaddr_storage
结构,然后查看其ss_family
字段以了解是否转换sockaddr_storage
数据到sockaddr_in
或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);
}