ドキュメントによると:
また、lpFrom と lpFromlen で示される値は、完了自体が示されるまで更新されません。アプリケーションは、これらの値が更新されるまで、これらの値を使用したり妨害したりしてはなりません。したがって、アプリケーションは、これらのパラメーターに自動 (つまり、スタックベースの) 変数を使用してはなりません。
OVERLAPPED
通常、オーバーラップ I/O を使用する場合、 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()
とを介してソケット I/O に I/O 完了ポートを使用する場合に、より便利です。詳細については、次の記事を参照してください。GetQueuedCompletionStatus()
WSAWaitForMultipleEvents()
WSAGetOverlappedResult()
Windows Sockets 2.0: 完了ポートを使用してスケーラブルな Winsock アプリを作成する