根据文档:
此外,由 lpFrom 和 lpFromlen 指示的值在完成本身指示之前不会更新。应用程序在更新之前不得使用或干扰这些值,因此应用程序不得对这些参数使用自动(即基于堆栈的)变量。
通常,在使用重叠 I/O 时,您应该定义一个自定义结构,其中包含一个OVERLAPPED
or WSAOVERLAPPED
(取决于您使用的 API -WSAOVERLAPPED
在这种情况下)以及您需要的任何其他数据(例如sockaddr_in
这种情况下的缓冲区)。然后分配结构的动态实例并将其数据成员传递给WSARecvFrom()
并等待操作完成,然后释放结构的内存。这样,当操作重叠的操作自己进行时,内存仍然有效。例如:
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()
如果您通过and为您的套接字 I/O 使用 I/O 完成端口GetQueuedCompletionStatus()
,而不是使用WSAWaitForMultipleEvents()
and ,这种方法会更加有用WSAGetOverlappedResult()
。阅读这篇文章了解更多详情:
Windows Sockets 2.0:使用完成端口编写可扩展的 Winsock 应用程序