使用重叠IO获取发件人的IP地址

时间:2011-12-20 21:50:14

标签: c++ networking winsock winsock2 overlapped-io

我知道WSARecvFrom有一个参数,用于返回发件人的IP地址。但是,当我使用重叠的io时,我传递的变量不会被填充。

WSARecvFrom(udpSocket, &receiveBuffer, 1, 0, &flags, (sockaddr*)&incomingAddress, &SocketAddressSize, &receiveOverlapped, 0)

...

WSAWaitForMultipleEvents(2, networkEvents, false, WSA_INFINITE, false)

...

WSAGetOverlappedResult(udpSocket, &receiveOverlapped, &transferCount, true, &flags);

...

char* incomingAddressString = inet_ntoa(incomingAddress.sin_addr);

incomingAddressString现在等于“204.204.204.204”

我错过了什么吗?

由于

1 个答案:

答案 0 :(得分:1)

根据documentation

  

此外,lpFrom和lpFromlen指示的值不会更新   直到完成本身表明。申请不得使用或   干扰这些值直到它们被更新,因此   应用程序不得使用自动(即基于堆栈)变量   对于这些参数。

通常,在使用重叠I / O时,您应该定义一个包含OVERLAPPEDWSAOVERLAPPED的自定义结构(取决于您使用的API - WSAOVERLAPPED在这种情况下)和您需要的其他数据(例如在这种情况下您的sockaddr_in缓冲区)。然后分配struct的动态实例并将其数据成员传递给WSARecvFrom()并等待操作完成,然后释放struct的内存。这样,当operlapped操作自行执行时,内存仍然有效。例如:

struct MyOverlappedInfo
{
    WSAOVERLAPPED Overlapped;
    DWORD Flags;
    sockaddr_in IncomingAddress;
    int IncomingAddressSize; 
    BYTE Data[1024];
    DWORD DataSize;
    WSABUF Buffer;

    MyOverlappedInfo()
    {
        memset(this, 0, sizeof(this));
        Overlapped.hEvent = WSACreateEvent();
        Buffer.len = sizeof(Data);
        Buffer.buf = (char*) Data;
    }

    ~MyOverlappedInfo()
    {
        WSACloseEvent(Overlapped.hEvent);
    }
};

MyOverlappedInfo info = new MyOverlappedInfo;

WSARecvFrom(udpSocket, &info->Buffer, 1, NULL, &info->Flags, (sockaddr*)&info->IncomingAddress, &info->IncomingAddressSize, &info->Overlapped, NULL);
... 
WSAWaitForMultipleEvents(2, networkEvents, false, WSA_INFINITE, false) 
... 
WSAGetOverlappedResult(udpSocket, &info->Overlapped, &info->DataSize, TRUE, &info->Flags); 
... 
char* incomingAddressString = inet_ntoa(info->IncomingAddress.sin_addr); 
delete info;

如果您通过CreateIOCompletionPort()GetQueuedCompletionStatus()为套接字I / O使用I / O完成端口,而不是使用WSAWaitForMultipleEvents()和{{1},则此方法更有用}。阅读这篇文章了解更多详情:

Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports