[windows] IOCP底层,支持超过15000个连接
来源:互联网 发布:阿里云文档管理 编辑:程序博客网 时间:2024/04/19 22:13
From: http://blog.csdn.net/educast/article/details/14523457
#pragma comment(lib, "ws2_32.lib")#include <winsock2.h>#include <stdio.h>//////////////////////////////////////////////////////////////////////////// 仅供测试软件用#define DATA_BUFSIZE 1024 // 接收缓冲区大小typedef enum{ IOSEND,IORECV,IOQUIT } IO_TYPE;typedef struct _SOCKET_INFORMATION {OVERLAPPED Overlapped;SOCKET Socket;IO_TYPE IoType;charbuffer[DATA_BUFSIZE];WSABUFDataBuf;DWORD BytesSEND;DWORD BytesRECV;} SOCKET_INFORMATION, * LPSOCKET_INFORMATION;DWORD Flags = 0,Bytes = 0;DWORD WINAPI WorkThread(LPVOID CompletionPortID);DWORD WINAPI AcceptThread(LPVOID lpParameter){WSADATA wsaData;HANDLE hCompPort;DWORD ThreadID;DWORD Ret;if ((Ret = WSAStartup(0x0202, &wsaData)) != 0){printf("WSAStartup failed with error %d\n", Ret);return FALSE;}if ((hCompPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL){printf( "CreateIoCompletionPort failed with error: %d\n", GetLastError());return FALSE;}// 根据CPU个数来创建线程,以达到最佳性能SYSTEM_INFO SystemInfo;GetSystemInfo(&SystemInfo);printf("processors=%d\n", SystemInfo.dwNumberOfProcessors);for(unsigned int i=0; i<SystemInfo.dwNumberOfProcessors*2; i++){HANDLE ThreadHandle;if ((ThreadHandle = CreateThread(NULL, 0, WorkThread, hCompPort, 0, &ThreadID)) == NULL){printf("CreateThread() failed with error %d\n", GetLastError());return FALSE;}CloseHandle(ThreadHandle);}SOCKET ListenSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, NULL, WSA_FLAG_OVERLAPPED);SOCKADDR_IN ServerAddr;ServerAddr.sin_family = AF_INET;ServerAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);ServerAddr.sin_port = htons(7999);bind(ListenSocket,(LPSOCKADDR)&ServerAddr,sizeof(ServerAddr));listen(ListenSocket,100);printf("listenning...\n");SOCKADDR_IN ClientAddr;int addr_length = sizeof(ClientAddr);while (TRUE){LPSOCKET_INFORMATION SI = new SOCKET_INFORMATION;if ((SI->Socket = accept(ListenSocket,(SOCKADDR*)&ClientAddr, &addr_length)) != INVALID_SOCKET){printf("accept ip:%s port:%d\n",inet_ntoa(ClientAddr.sin_addr),ClientAddr.sin_port);// 相关参数初始化memset(&SI->Overlapped,0,sizeof(WSAOVERLAPPED));memset(SI->buffer, 0, DATA_BUFSIZE);SI->DataBuf.buf = SI->buffer;SI->DataBuf.len = DATA_BUFSIZE;SI->BytesRECV = 0;SI->BytesSEND = 0;SI->IoType = IORECV;if (CreateIoCompletionPort((HANDLE)SI->Socket, hCompPort, (DWORD)SI, 0) == NULL){printf("CreateIoCompletionPort failed with error %d\n", GetLastError());return FALSE;}// 发出一个重叠I\O请求if(WSARecv(SI->Socket, &SI->DataBuf, 1, &Bytes, &Flags, &SI->Overlapped, NULL) == SOCKET_ERROR){if(WSAGetLastError() != WSA_IO_PENDING){printf("disconnect\n");closesocket(SI->Socket);delete SI;continue;}}}}return FALSE;}DWORD WINAPI WorkThread(LPVOID CompletionPortID){HANDLE hCompPort = (HANDLE)CompletionPortID;while (TRUE){DWORD BytesTransferred = 0;LPSOCKET_INFORMATION SI = NULL;LPWSAOVERLAPPED Overlapped = NULL;// 线程进入线程池,等待被唤醒if (GetQueuedCompletionStatus(hCompPort, &BytesTransferred, (LPDWORD)&SI, &Overlapped, INFINITE)){if (0 == BytesTransferred && IOQUIT != SI->IoType){printf("disconnect\n");closesocket(SI->Socket); delete SI;continue;}switch(SI->IoType){case IORECV:{printf("%s \n", SI->buffer);// 目前的功能是将接收到的数据原封不动的返回SI->DataBuf.len = BytesTransferred;SI->BytesRECV = BytesTransferred;SI->IoType = IOSEND;if (WSASend(SI->Socket, &SI->DataBuf, 1, &Bytes, Flags, &SI->Overlapped, NULL) == SOCKET_ERROR){if(WSAGetLastError() != WSA_IO_PENDING){printf("disconnect\n");closesocket(SI->Socket); delete SI;continue;}}break;}case IOSEND:{SI->BytesSEND += BytesTransferred;//返回是否彻底,若未发完,接着发if (SI->BytesSEND < SI->BytesRECV){SI->DataBuf.buf += BytesTransferred; SI->DataBuf.len -= BytesTransferred; SI->IoType = IOSEND;if (WSASend(SI->Socket, &SI->DataBuf, 1, &Bytes, Flags, &SI->Overlapped, NULL) == SOCKET_ERROR){if(WSAGetLastError() != WSA_IO_PENDING){printf("disconnect\n");closesocket(SI->Socket); delete SI;continue;}}}else if (SI->BytesSEND > SI->BytesRECV){printf("BytesSEND:%d > BytesRECV:%d\n", SI->BytesSEND,SI->BytesRECV);memset(SI->buffer, 0, DATA_BUFSIZE);SI->BytesRECV = 0;SI->BytesSEND = 0;SI->IoType = IORECV;SI->DataBuf.len = DATA_BUFSIZE;SI->DataBuf.buf = SI->buffer;}else{memset(SI->buffer, 0, DATA_BUFSIZE);SI->BytesRECV = 0;SI->BytesSEND = 0;SI->IoType = IORECV;SI->DataBuf.len = DATA_BUFSIZE;SI->DataBuf.buf = SI->buffer;if (WSARecv(SI->Socket, &SI->DataBuf, 1, &Bytes, &Flags, &SI->Overlapped, NULL) == SOCKET_ERROR){if(WSAGetLastError() != WSA_IO_PENDING){printf("disconnect\n");closesocket(SI->Socket); delete SI;continue;}}}break;}case IOQUIT:{// 让线程安全退出return FALSE;break;}default:break;}} } return FALSE;}void main() {HANDLE hThreads = CreateThread(NULL, 0, AcceptThread, NULL, NULL, NULL);WaitForSingleObject(hThreads, INFINITE);printf("exit\n");CloseHandle(hThreads);}
用VS2012 新建windows 控制台应用程序,空项目,新建文件main.cpp, 粘贴以上代码,直接编译,应该能通过。
0 0
- [windows] IOCP底层,支持超过15000个连接
- IOCP底层,支持超过15000个连接
- Windows IOCP
- Windows IOCP
- 65000个有效连接的IOCP封装类
- windows 下面解决远程终端连接已经超过
- windows编程 如何等待超过64个线程
- IOCP服务端连接测试
- IOCP连接关闭
- IOCP--Windows服务器编程
- windows-IOCP模型总结
- nginx iocp for windows
- windows-IOCP模型总结
- windows IOCP模型
- 底层工具库支持
- Linux 打开默认串口支持数量超过4个的方法
- Linux 打开默认串口支持数量超过4个的方法
- 让 32 位 windows 7 支持超过 4G 内存(PAE)
- 学术休假---字符类型个数
- 【Eclipse】eclipse上安装Easy Explorer/open explorer插件实现在Eclipse界面上直接打开文件
- iphone怎样和威威上车载蓝牙连接
- linux命令行选项的常见约定
- 负载均衡常用方式
- [windows] IOCP底层,支持超过15000个连接
- 2015年工作中遇到的问题:61-70
- 装箱子
- 关于aix上的filesystemcache
- HDU 2102 A计划 (DFS)
- Windows IOCP模型与Linux EPOLL模块之比较
- CodeForces 417D Cunning Gena 状压dp
- webview使用
- 去湖南长沙浏阳出差