2012-04-05 20 views
1

サーバでクライアントのIPアドレスとポートを取得する必要があります。サーバーはIOCPを使用してC++で書かれているので、クライアントを受け入れずに新しいソケットを作成し、この準備完了ソケットで(AcceptEx)クライアントを受け入れます。そしてそれのために構造体sockaddr_inは正​​しくありません。IOCPを使用してクライアントの実際のIPアドレスとポートを取得する方法は?

どうすればいいですか?

ありがとうございます!

答えて

5

AcceptExは、お使いのアドレスとピアアドレス(ip + port of 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 
); 

あなたは、その後、2つの返されたアドレスを保持するのに十分な大きさのバッファを上のポイントにlpOutputBufferを指定する必要があります。 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); 
関連する問題