1

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」に等しくなりました

何か不足していますか?

ありがとう

4

1 に答える 1

1

ドキュメントによると:

また、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 アプリを作成する

于 2011-12-20T22:26:11.030 に答える