// 重叠IO网络模式.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include#include #include using namespace std;#pragma comment (lib,"ws2_32.lib")#define PORT 6000#define MSGSIZE 1024typedef struct { WSAOVERLAPPED overlap; WSABUF Buffer; char szMessage[MSGSIZE]; DWORD NumberOfBytesRecvd; DWORD Flags;}PER_IO_OPERATION_DATA,*LPPER_IO_OPERATION_DATA;int g_iToalComn = 0;SOCKET g_CliSocketArr[MAXIMUM_WAIT_OBJECTS];WSAEVENT g_CliEventArr[MAXIMUM_WAIT_OBJECTS];LPPER_IO_OPERATION_DATA g_pPerIODataArr[MAXIMUM_WAIT_OBJECTS];DWORD WINAPI WorkerThread(LPVOID lparam);void Cleanup(int);bool InitNetEvn(){ WSADATA wsa; if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) { cout << "网络环境失败" << endl; return false; } if (LOBYTE(wsa.wVersion)!=2||HIBYTE(wsa.wVersion)!=2) { cout << "版本号不对" << endl; return false; } return true;}int main(){ SOCKET sListen, sClient; SOCKADDR_IN local, client; DWORD dwThreadId; int iaddrSize = sizeof(SOCKADDR_IN); if (!InitNetEvn()) { return -1; } sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); local.sin_addr.S_un.S_addr = htonl(INADDR_ANY); local.sin_family = AF_INET; local.sin_port = htons(PORT); bind(sListen, (sockaddr *)&local, iaddrSize); listen(sListen, 3); CreateThread(NULL, NULL, WorkerThread, NULL, NULL, &dwThreadId); while (TRUE) { sClient = accept(sListen, (sockaddr *)&client, &iaddrSize); printf("Accept client:%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); g_CliSocketArr[g_iToalComn] = sClient; g_pPerIODataArr[g_iToalComn] = (LPPER_IO_OPERATION_DATA)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PER_IO_OPERATION_DATA)); g_pPerIODataArr[g_iToalComn]->Buffer.len = MSGSIZE; g_pPerIODataArr[g_iToalComn]->Buffer.buf = g_pPerIODataArr[g_iToalComn]->szMessage; g_CliEventArr[g_iToalComn] = g_pPerIODataArr[g_iToalComn]->overlap.hEvent = WSACreateEvent(); WSARecv( g_CliSocketArr[g_iToalComn], &g_pPerIODataArr[g_iToalComn]->Buffer, 1, &g_pPerIODataArr[g_iToalComn]->NumberOfBytesRecvd, &g_pPerIODataArr[g_iToalComn]->Flags, &g_pPerIODataArr[g_iToalComn]->overlap, NULL); g_iToalComn++; } closesocket(sListen); WSACleanup(); return 0;}DWORD WINAPI WorkerThread(LPVOID lparam){ int ret, index; DWORD cbTransferred; while (true) { //判断出一个重叠IO调用是否完成 ret = WSAWaitForMultipleEvents(g_iToalComn, g_CliEventArr, FALSE, 1000, FALSE); if (ret==WSA_WAIT_TIMEOUT||ret==WSA_WAIT_FAILED) { continue; } index = ret - WSA_WAIT_EVENT_0; WSAResetEvent(g_CliEventArr[index]); WSAGetOverlappedResult( g_CliSocketArr[index], &g_pPerIODataArr[index]->overlap, &cbTransferred, TRUE, &g_pPerIODataArr[index]->Flags); if (cbTransferred==0) { Cleanup(index); } else { g_pPerIODataArr[index]->szMessage[cbTransferred] = '\0'; send(g_CliSocketArr[index], g_pPerIODataArr[index]->szMessage, \ cbTransferred, 0); WSARecv( g_CliSocketArr[index], &g_pPerIODataArr[index]->Buffer, 1, &g_pPerIODataArr[index]->NumberOfBytesRecvd, &g_pPerIODataArr[index]->Flags, &g_pPerIODataArr[index]->overlap, NULL); } } return 0;}void Cleanup(int index){ closesocket(g_CliSocketArr[index]); WSACloseEvent(g_CliEventArr[index]); HeapFree(GetProcessHeap(), 0, g_pPerIODataArr[index]); if (index