非同期 I/O を学習しようとしています。
私のプログラムはソケットを作成し、AcceptEx で受け入れるか、connect で接続します。そのメイン スレッドではループ内で WaitForMultipleObjects() を呼び出しますが、名前を解決するスレッドを作成し、connect() を呼び出し、最初の ReadFile() を呼び出します。
これらのスレッドは、ReadFile() を呼び出した後に終了し、メイン スレッドに読み取り結果を待機させます。
何らかの理由で、接続スレッドが終了した後、読み取り操作がキャンセルされ、イベントがトリガーされ、GetOverlappedResult() が ERROR_OPERATION_ABORTED で失敗します。
例:
#define _WIN32_WINNT 0x0501
#include <winsock2.h>
#include <ws2tcpip.h>
#include <wspiapi.h>
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define BUFSZ 2048
#define PORT 80
#define HOST "192.168.2.1"
#define HOST "stackoverflow.com"
static struct {
char buf[BUFSZ];
OVERLAPPED overlap;
SOCKET sock;
} x = { 0 };
static DWORD WINAPI barthread(LPVOID param) {
static struct sockaddr_in inaddr = { 0 };
int rc;
BOOL b;
DWORD dw;
DWORD nb;
LPHOSTENT lphost;
x.sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
inaddr.sin_family = AF_INET;
lphost = gethostbyname(HOST);
inaddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
inaddr.sin_port = htons(PORT);
rc = connect(x.sock, (struct sockaddr *)&inaddr, sizeof(struct sockaddr_in));
if (rc == 0) {
printf("thread 2 connected\n");
printf("thread 2 call ReadFile\n");
b = ReadFile((HANDLE)x.sock, x.buf, BUFSZ, &nb, &x.overlap);
dw = GetLastError();
if (b || dw == ERROR_IO_PENDING) {
printf("thread 2 ReadFile ok\n");
} else {
printf("thread 2 ReadFile failed\n");
}
printf("thread 2 sleeping\n");
Sleep(3000);
printf("thread 2 dying\n");
}
return 0;
}
int main(int argc, char* argv[])
{
WSADATA WD;
BOOL b;
DWORD dw;
DWORD nb;
DWORD tid;
WSAStartup(MAKEWORD(2, 0), &WD);
x.overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
CreateThread(NULL, 0, barthread, NULL, 0, &tid);
dw = WaitForSingleObject(x.overlap.hEvent, INFINITE);
printf("thread 1 event triggered\n");
b = GetOverlappedResult((HANDLE)x.sock, &x.overlap, &nb, FALSE);
dw = GetLastError();
printf("thread 1 GetOverlappedResult() = %d, GetLastError() = %d\n", b, dw);
return 0;
}