//#include <stdio.h> //#include "CIOCPServer.h" #include <stdio.h> #include <winsock2.h> #include <WS2tcpip.h> #pragma comment(lib,"ws2_32.lib") #include <string.h> #include <map> #define DATA_BUFSIZE 8192 typedef struct { OVERLAPPED Overlapped; WSABUF DataBuf; CHAR Buffer[DATA_BUFSIZE]; DWORD BytesSEND; DWORD BytesRECV; } PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA; typedef struct { SOCKET Socket; } PER_HANDLE_DATA, * LPPER_HANDLE_DATA; //int _stdcall DWORD WINAPI RecvThread(LPVOID lpParameter)//接收消息线程 { HANDLE ComplectionPort = (HANDLE)lpParameter; DWORD BytesTransferred; LPPER_HANDLE_DATA sClient; LPPER_IO_OPERATION_DATA PerIoData;//缓冲区 代表每次从从缓存区拿256个字节处理 DWORD Flags; DWORD RecvBytes; while (1) { int nLen; //先接收长度 printf("1"); GetQueuedCompletionStatus( ComplectionPort, &BytesTransferred, //传递长度 (LPDWORD)&sClient, (LPOVERLAPPED*)&PerIoData, INFINITE); memset(PerIoData, 0, sizeof(PER_IO_OPERATION_DATA)); PerIoData->BytesSEND = 0; PerIoData->BytesRECV = 0; PerIoData->DataBuf.len = DATA_BUFSIZE; PerIoData->DataBuf.buf = PerIoData->Buffer; Flags = 0; WSARecv( sClient->Socket, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags, &(PerIoData->Overlapped), NULL); int a = 1; } //nagle算法 //关闭初始化 return 0; } int main() { SOCKADDR_IN InternetAddr; SOCKET Listen; SOCKET Accept; HANDLE CompletionPort; SYSTEM_INFO SystemInfo; LPPER_HANDLE_DATA PerHandleData; LPPER_IO_OPERATION_DATA PerIoData; int i; DWORD RecvBytes; DWORD Flags; DWORD ThreadID; WSADATA wsaData; DWORD Ret; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("WSAStartup error%08X", WSAGetLastError()); return 0; } //1.初始化套接字 SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //完成端口创建 CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); //2.绑定端口 sockaddr_in addr; //转换大小尾 addr.sin_family = AF_INET; addr.sin_port = htons(12345); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); if (bind(s, (sockaddr*)&addr, sizeof(addr)) != 0) { printf("WSAStartup error%08X", WSAGetLastError()); return 0; } //3.监听 设置队列连接数 listen(s, 100); //4.收客户连接 sockaddr_in caddr; //客户端地址 int nLength = sizeof(caddr); int fl = 1; while (true) { SOCKET sTCP = accept(s, (sockaddr*)&caddr, &nLength); //收发数据 返回成功说明已经3次握手连接 char IPdotdec[20]; //存放点分十进制IP地址 inet_ntop(AF_INET, &caddr.sin_addr, IPdotdec, 16);//点阵转换ip printf("ip:%s,port:%d\n", IPdotdec, htons(caddr.sin_port)); if ((PerHandleData = (LPPER_HANDLE_DATA)GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA))) == NULL) { printf("GlobalAlloc() failed with error %d\n", GetLastError()); return 0; } PerHandleData->Socket = sTCP; //完成端口 CreateIoCompletionPort((HANDLE)sTCP, CompletionPort, (DWORD)PerHandleData, 0); // 创建同下面的WSARecv调用相关的IO套接字信息结构体 //开辟空间 //PerIoData = (LPPER_IO_OPERATION_DATA)HeapAlloc( // GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LPPER_IO_OPERATION_DATA) //); // //清管子的数据结构,准备往里面灌数据 // if ((PerIoData = (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA))) == NULL) { printf("GlobalAlloc() failed with error %d\n", GetLastError()); return 0; } ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED)); PerIoData->BytesSEND = 0; PerIoData->BytesRECV = 0; PerIoData->DataBuf.len = DATA_BUFSIZE; PerIoData->DataBuf.buf = PerIoData->Buffer; Flags = 0; WSARecv( sTCP, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags, &(PerIoData->Overlapped), NULL); if (fl) { CreateThread(NULL, 0, RecvThread, (LPVOID)CompletionPort, 0, NULL); fl = 0; } } //nagle算法 //关闭初始化 closesocket(s); //反初始化库 WSACleanup(); return 0; }