如何使用IOCP获取客户端真正的IP地址和端口?

时间:2012-04-05 11:43:39

标签: c++ sockets winsock iocp

我需要在服务器中使用ip-address和客户端端口。使用IOCP在C ++上编写的服务器,所以我不接受客户端,我创建新的套接字然后在这个就绪套接字上接受(AcceptEx)客户端。因为它结构sockaddr_in不正确。

我该怎么做?

谢谢!

1 个答案:

答案 0 :(得分:5)

AcceptEx可能会返回您的对等地址(TCP套接字的IP +端口)。

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个返回的地址,然后。 dwLocalAddressLengthdwRemoteAddressLength应设置为缓冲区中保留的地址大小。

根据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
     

正在使用的传输协议的长度。

当然缓冲区必须对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);