重叠IO

简介:  // NetWork.cpp : Defines the entry point for the console application.

 

// NetWork.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <Winsock2.h> #include <Windows.h> #include <process.h> #pragma comment(lib, "WS2_32.lib") #define MAX_BUFFER 256 #define MAX_TIMEOUT 1000 typedef enum _OPERATION_INFO { OP_NULL, OP_READ, OP_WRITE }OPERATIONINFO; typedef struct _OVERLAPPED_INFO_ { public: _OVERLAPPED_INFO_() { Clean(); } ~_OVERLAPPED_INFO_() { Clean(); } protected: void Clean() { ol.hEvent = NULL; sock = INVALID_SOCKET; memset(&addr, 0, sizeof(addr)); addr.sin_addr.S_un.S_addr = INADDR_ANY; addr.sin_family = AF_INET; addr.sin_port = htons(0); wsaBuf.buf = szBuf; wsaBuf.len = MAX_BUFFER; memset(szBuf, 0, sizeof(szBuf)); nOpType = OP_NULL; } public: WSAOVERLAPPED ol; SOCKET sock; SOCKADDR_IN addr; WSABUF wsaBuf; char szBuf[MAX_BUFFER]; OPERATIONINFO nOpType; }OVERLAPPEDINFO, *POVERLAPPEDINFO; WSAEVENT g_event[WSA_MAXIMUM_WAIT_EVENTS] = {0}; OVERLAPPEDINFO* g_ol[WSA_MAXIMUM_WAIT_EVENTS] = {0}; int g_nIndex = 0; BOOL g_bExitThread = FALSE; unsigned __stdcall ThreadProc(LPVOID lParam); int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsaData; if(0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) { printf("WSAStartup failed with error code: %d/n", GetLastError()); return EXIT_FAILURE; } if(2 != HIBYTE(wsaData.wVersion) || 2 != LOBYTE(wsaData.wVersion)) { printf("Socket version not supported./n"); WSACleanup(); return EXIT_FAILURE; } SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(INVALID_SOCKET == sListen) { printf("socket failed with error code: %d/n", WSAGetLastError()); WSACleanup(); return EXIT_FAILURE; } SOCKADDR_IN addr = {0}; addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); addr.sin_family = AF_INET; addr.sin_port = htons(5050); if(SOCKET_ERROR == bind(sListen, (LPSOCKADDR)&addr, sizeof(addr))) { printf("bind failed with error code: %d/n", WSAGetLastError()); closesocket(sListen); sListen = INVALID_SOCKET; WSACleanup(); return EXIT_FAILURE; } if(SOCKET_ERROR == listen(sListen, 5)) { printf("listen failed with error code: %d/n", WSAGetLastError()); closesocket(sListen); sListen = INVALID_SOCKET; WSACleanup(); return EXIT_FAILURE; } HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, NULL); if(NULL == hThread) { printf("_beginthreadex failed with error code: %d/n", GetLastError()); closesocket(sListen); sListen = INVALID_SOCKET; WSACleanup(); return EXIT_FAILURE; } printf("Server start listen and wait for client to connect .../n"); SOCKADDR_IN remote = {0}; int len = sizeof(remote); while(TRUE) { if(g_nIndex >= WSA_MAXIMUM_WAIT_EVENTS) { printf("Too many connect, wait for disconnect .../n"); continue; } SOCKET sNew = accept(sListen, (LPSOCKADDR)&remote, &len); if(INVALID_SOCKET == sNew) { printf("accept failed with error code: %d/n", WSAGetLastError()); continue; } printf("<IP: %s, Port: %d> client come in./n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port)); DWORD dwTrans = 0; DWORD dwFlags = 0; g_ol[g_nIndex] = new OVERLAPPEDINFO; g_ol[g_nIndex]->sock = sNew; memcpy(&g_ol[g_nIndex]->addr, &remote, sizeof(remote)); g_event[g_nIndex] = g_ol[g_nIndex]->ol.hEvent = WSACreateEvent(); g_ol[g_nIndex]->nOpType = OP_READ; if(SOCKET_ERROR == WSARecv(g_ol[g_nIndex]->sock, &(g_ol[g_nIndex]->wsaBuf), 1, &dwTrans, &dwFlags, (LPWSAOVERLAPPED)&(g_ol[g_nIndex]->ol), NULL)) { if(ERROR_IO_PENDING != WSAGetLastError()) { printf("WSARecv failed with error code: %d/n", WSAGetLastError()); closesocket(g_ol[g_nIndex]->sock); delete g_ol[g_nIndex]; g_ol[g_nIndex] = NULL; continue; } } g_nIndex++; } // End of thread and exit process g_bExitThread = TRUE; // Exit thread. WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); WSACleanup(); return 0; } unsigned __stdcall ThreadProc(LPVOID lParam) { while(!g_bExitThread) { DWORD dwTrans = 0; DWORD dwFlags = 0; DWORD dwIndex = WSAWaitForMultipleEvents(g_nIndex, g_event, FALSE, MAX_TIMEOUT, FALSE); if(WSA_WAIT_FAILED == dwIndex || WSA_WAIT_TIMEOUT == dwIndex) { continue; } dwIndex -= WSA_WAIT_EVENT_0; for(int i = dwIndex; i < g_nIndex; i++) { dwIndex = WSAWaitForMultipleEvents(1, &g_event[dwIndex], TRUE, INFINITE, FALSE); if(WSA_WAIT_FAILED == dwIndex) { continue; } dwIndex -= WSA_WAIT_EVENT_0; WSAResetEvent(g_event[dwIndex]); BOOL bRet = WSAGetOverlappedResult(g_ol[dwIndex]->sock, &(g_ol[dwIndex]->ol), &dwTrans, FALSE, &dwFlags); if(bRet) { if(dwTrans > 0) { switch(g_ol[dwIndex]->nOpType) { case OP_READ: { printf("recv client

目录
相关文章
|
5月前
|
缓存 Linux API
文件IO和标准IO的区别
文件IO和标准IO的区别
56 2
|
4月前
|
IDE Linux 程序员
技术经验解读:【转】IO空间,IO端口,MMIO
技术经验解读:【转】IO空间,IO端口,MMIO
159 0
|
2月前
|
消息中间件 网络协议 Java
你不得不了解的网络IO模型知识
该文章主要讲述了网络I/O模型的相关知识,包括不同的I/O模型以及它们的特点和应用场景。
你不得不了解的网络IO模型知识
|
5月前
|
缓存 Java Unix
五种网络IO模型
前言   本文重点在于介绍五种网络IO模型
485 0
|
11月前
网络IO 多路IO复用 之 select
网络IO 多路IO复用 之 select
|
缓存 Java Linux
网络IO模型总结
网络IO模型总结
101 0
|
网络协议 Java Unix
四种IO模型详解下
《基础系列》
121 0
|
存储 Java Linux
【网络IO】细说网络IO模型【一】
面试官:我们来简单聊一下网络IO相关东西吧,嗯?不了解是吧,没关系,那今天面试就先到这了。。。
194 0
【网络IO】细说网络IO模型【一】
|
存储 监控 Unix