我知道 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”
我错过了什么吗?
谢谢
最佳答案
根据documentation :
Also, the values indicated by lpFrom and lpFromlen are not updated until completion is itself indicated. Applications must not use or disturb these values until they have been updated, therefore the application must not use automatic (that is, stack-based) variables for these parameters.
通常,当使用重叠 I/O 时,您应该定义一个包含 OVERLAPPED
或 WSAOVERLAPPED
的自定义结构(取决于您使用的 API - WSAOVERLAPPED
在这种情况下)以及您需要的任何其他数据(例如在这种情况下您的 sockaddr_in
缓冲区)。然后分配该结构的动态实例并将其数据成员传递给 WSARecvFrom()
并等待操作完成,然后再为该结构释放内存。这样,当 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()
和 WSAGetOverlappedResult()
。阅读这篇文章了解更多详情:
Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports
关于c++ - 使用重叠 IO 获取发件人的 IP 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8582436/