Windows で IOCP を使用し、C++ でマルチクライアント サーバーを実装する方法

Windows システムでは、IOCP(入出力完了ポート) を使用して、高性能の I/O 多重化メカニズムを実現できます。IOCPこれは、Windows システムの効率的な非同期 I/O メカニズムであり、同時実行性の高いネットワーク サーバーの実装に使用できます。IOCPマルチクライアント サーバーを実装するために使用する基本的な手順は次のとおりです。

  1. ソケットを作成する

たとえば、関数を使用してsocketTCP サーバー ソケットを作成します。

#include <winsock2.h>

WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);

SOCKET server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(8888);
bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address));
listen(server_socket, 10);
  1. IOCP オブジェクトを作成する

この関数を使用してCreateIoCompletionPortIOCP オブジェクトを作成し、サーバー ソケットを IOCP オブジェクトに関連付けます。次に例を示します。

HANDLE iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
CreateIoCompletionPort((HANDLE)server_socket, iocp, 0, 0);
  1. 接続リクエストを処理する

関数を使用してAcceptExクライアント接続要求を監視し、新しいクライアント ソケットを IOCP オブジェクトに関連付けます。次に例を示します。

LPFN_ACCEPTEX AcceptExFunc;
GUID GuidAcceptEx = WSAID_ACCEPTEX;
DWORD dwBytes = 0;
WSAIoctl(server_socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidAcceptEx, sizeof(GuidAcceptEx), &AcceptExFunc, sizeof(AcceptExFunc), &dwBytes, NULL, NULL);

SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
int address_length = sizeof(struct sockaddr_in);
char accept_buffer[2 * (sizeof(struct sockaddr_in) + 16)];
AcceptExFunc(server_socket, client_socket, accept_buffer, 0, sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16, NULL, NULL);
CreateIoCompletionPort((HANDLE)client_socket, iocp, (ULONG_PTR)client_socket, 0);
  1. I/O完了イベントを処理する

関数を使用しGetQueuedCompletionStatusて I/O 完了イベントを取得し、読み取りおよび書き込み操作を処理します。次に例を示します。

while (true) {
    DWORD bytes_transferred = 0;
    ULONG_PTR completion_key = 0;
    LPOVERLAPPED overlapped = NULL;
    GetQueuedCompletionStatus(iocp, &bytes_transferred, &completion_key, &overlapped, INFINITE);

    if (bytes_transferred == 0) {
        closesocket((SOCKET)completion_key);
        printf("Client disconnected\n");
        continue;
    }

    SOCKET client_socket = (SOCKET)completion_key;
    if (overlapped == NULL) {
        char buffer[1024] = {0};
        recv(client_socket, buffer, bytes_transferred, 0);
        printf("Received data: %s\n", buffer);
    } else {
        WSABUF buffer;
        buffer.buf = new char[1024];
        buffer.len = 1024;
        DWORD flags = 0;
        WSARecv(client_socket, &buffer, 1, NULL, &flags, overlapped, NULL);
    }
}
  1. データを送る

クライアント ソケットを使用してデータを送信します。次に例を示します。

char* data = "Hello, world!";
send(client_socket, data, strlen(data), 0);

上記はIOCPマルチクライアント サーバーを実装するための基本的な手順ですが、IOCPコードは比較的複雑であり、非同期 I/O やイベント駆動型プログラミングなどの概念を理解する必要があることに注意してください。

おすすめ

転載: blog.csdn.net/CHNIM/article/details/130891079