AcceptEx
may return you both your and peer addresses (ip+port of TCP sockets).
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
);
You should specify lpOutputBuffer
to point on a buffer with enough size to hold 2 returned addresses, then . dwLocalAddressLength
and dwRemoteAddressLength
should be set to the address size reserved in the buffer.
According to MSDN the buffer size required for a single address (for AcceptEx
function) is 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.
Of course the buffer must be valid for the I/O duration. You may put it inside your OVERLAPPED
structure. Something like this:
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);
After the I/O has (successfully) completed you may get the addresses:
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);