我需要在服务器中获取客户端的 IP 地址和端口。使用 IOCP 在 C++ 上编写的服务器,所以我不接受客户端,我创建新的套接字,然后在这个准备好的套接字上接受 (AcceptEx) 客户端。因此 struct sockaddr_in 是不正确的。
我该怎么做?
谢谢!
最佳答案
AcceptEx
可能会返回您的地址和对端地址(IP+TCP 套接字端口)。
BOOL AcceptEx(
__in SOCKET sListenSocket,
__in SOCKET sAcceptSocket,
__in PVOID lpOutputBuffer,
__in DWORD dwReceiveDataLength,
__in DWORD dwLocalAddressLength,
__in DWORD dwRemoteAddressLength,
__out LPDWORD lpdwBytesReceived,
__in LPOVERLAPPED lpOverlapped
);
您应该指定 lpOutputBuffer
指向一个大小足以容纳 2 个返回地址的缓冲区,然后 . dwLocalAddressLength
和 dwRemoteAddressLength
应设置为缓冲区中保留的地址大小。
根据 MSDN,单个地址(对于 AcceptEx
函数)所需的缓冲区大小为 sizeof(SOCKADDR_IN) + 16
:
dwLocalAddressLength [in] The number of bytes reserved for the local address information. This value must be at least 16 bytes more than the maximum address
length for the transport protocol in use.
当然,缓冲区必须在 I/O 持续时间内有效。你可以把它放在你的 OVERLAPPED
结构中。像这样:
struct OverlappedAccept
:public OVERLAPPED
{
// some context information that you need
// ...
// Buffer for addresses
struct {
BYTE m_pLocal[sizeof(SOCKADDR_IN) + 16];
BYTE m_pRemote[sizeof(SOCKADDR_IN) + 16];
} m_Bufs;
};
// start accept operation
OverlappedAccept* pOver = /* ... */;
BOOL bRet = AcceptEx(
hSockListen,
hSockNew,
&pOver->m_Bufs,
0,
sizeof(pOver->m_Bufs.m_pLocal),
sizeof(pOver->m_Bufs.m_pRemote),
&dwBytes,
pOver);
在 I/O(成功)完成后,您可以获得地址:
sockaddr *pLocal = NULL, *pRemote = NULL;
int nLocal = 0, nRemote = 0;
GetAcceptExSockAddrs(
&pOver->m_Bufs,
0,
sizeof(pOver->m_Bufs.m_pLocal),
sizeof(pOver->m_Bufs.m_pRemote),
&pLocal,
&nLocal,
&pRemote,
&nRemote);
关于c++ - 如何使用 IOCP 获取客户端真实 IP 地址和端口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10027940/