2012-04-05 130 views
1

我需要服務器端的客戶端IP地址和端口號。使用IOCP在C++上編寫的服務器,所以我不接受客戶端,我創建了新的套接字,然後在此套接字上接受(AcceptEx)客戶端。並因爲它struct sockaddr_in不正確。如何使用IOCP獲取客戶端的真實IP地址和端口?

我該怎麼做?

謝謝!

回答

5

AcceptEx可能會返回您和您的對端地址(TCP端口的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返回的地址,然後。應該將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); 

在我之後/ 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); 
相關問題