1

サーバーでクライアントのIPアドレスとポートを取得する必要があります。サーバーは IOCP を使用して C++ で記述されているため、クライアントを受け入れません。新しいソケットを作成してから、この準備ができたソケットでクライアントを受け入れます (AcceptEx)。そのため、 struct sockaddr_in は正しくありません。

これどうやってするの?

ありがとう!

4

1 に答える 1

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);
于 2012-04-05T11:57:05.613 に答える