活动介绍
file-type

Windows平台的五种IO模型详解

PDF文件

下载需积分: 9 | 15.23MB | 更新于2024-07-26 | 87 浏览量 | 8 下载量 举报 收藏
download 立即下载
"这篇文章主要介绍了IO服务器模型,特别是Windows平台上的五种IO模型:异步I/O模型、选择模型(select)、异步选择(WSAAsyncSelect)、事件选择(WSAEventSelect)以及重叠I/O(OverlappedI/O)。其中,选择模型是最常见的,它通过select函数来监控多个套接字的读写状态,避免阻塞并防止WSAEWOULDBLOCK错误。" 在IT行业中,IO服务器模型是构建高性能网络服务的基础,特别是在服务器端编程时,正确选择和理解IO模型至关重要。Windows操作系统提供了多种IO模型供开发者选择,每种模型都有其特定的应用场景和优缺点。 1. 异步I/O模型:这种模型允许应用程序在发起I/O操作后立即返回,继续执行其他任务,而I/O操作由操作系统在后台完成。当操作完成时,系统会通知应用程序。这种模型适合处理大量并发连接,但实现相对复杂。 2. 选择模型 - select:select函数是这个模型的核心,它可以监视多个文件描述符(在Windows中通常是套接字),等待任意一个或多个描述符变为可读、可写或有异常。当有活动时,select会唤醒应用程序进行相应的读写操作。这种模型简单且可移植,但在大型系统中,由于描述符数量限制,效率可能较低。 3. 异步选择(WSAAsyncSelect):这是Windows特有的,允许应用程序注册事件回调,当指定的网络事件发生时,Windows会发送消息给应用程序进行处理。这种方式适合简单的小型应用,但在多线程环境中管理起来较为复杂。 4. 事件选择(WSAEventSelect):类似于WSAAsyncSelect,但使用Windows事件对象进行通知,更适合多线程环境,可以与其它Windows事件机制集成。 5. 重叠I/O(Overlapped I/O)或完成端口(Completion Port):这是Windows提供的高级I/O模型,特别适合高并发环境。重叠I/O允许异步操作,而完成端口则提供了一种高效的方式管理和调度这些异步操作,尤其适合大型服务器应用。 选择合适的IO模型时,需要考虑以下因素: - 应用程序的并发需求:并发连接数量大时,应选择能有效处理大量并发的模型,如完成端口。 - 扩展性:考虑未来可能的增长,选择易于扩展的模型。 - 可移植性:如果需要跨平台,选择标准如select的模型更合适。 - 系统资源:某些模型可能对系统资源(如内存、CPU)有较高要求,需权衡性能和资源消耗。 了解并熟练掌握这些IO模型对于开发高效的网络服务至关重要,不同的模型在不同场景下都能发挥出最佳效能。在设计和实现服务器应用时,应根据具体需求选择合适的IO模型,以确保程序的稳定性和性能。

相关推荐

filetype
重叠IO模型之OverLapped完成例程模型WSACompletionRoutineServer VS2010 基础入门 客户端与服务器端 客户端向服务器端发送数据 可接收多个客户端 #include #include #pragma comment (lib, "ws2_32.lib") #define PORT 8088 #define MSG_SIZE 1024 SOCKET g_sConnect; bool g_bConnect = false; typedef struct { WSAOVERLAPPED overLap; WSABUF wsaBuf; char chMsg[MSG_SIZE]; DWORD nRecvNum; DWORD nFlags; SOCKET sClient; }PRE_IO_OPERATION_DATA, *LP_PER_IO_OPERATION_DATA; void CALLBACK CompletionRoutine(DWORD dwError, DWORD dwTrans, LPWSAOVERLAPPED lpOverlap, DWORD nFlags); DWORD WINAPI workThread(LPVOID lp) { LP_PER_IO_OPERATION_DATA lpData; while(TRUE) { if (g_bConnect) // 有新的连接 { // 为lpData分配空间并初始化 lpData = (LP_PER_IO_OPERATION_DATA)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PRE_IO_OPERATION_DATA)); lpData->wsaBuf.len = MSG_SIZE; lpData->wsaBuf.buf = lpData->chMsg; lpData->sClient = g_sConnect; WSARecv(lpData->sClient, &lpData->wsaBuf, 1, &lpData->nRecvNum, &lpData->nFlags, &lpData->overLap, CompletionRoutine); g_bConnect = false; // 处理完毕 } SleepEx(1000, TRUE); } return 0; } // 系统在WSARecv收到信息后,自动调用此函数,并传入参数--回调函数 void CALLBACK CompletionRoutine(DWORD dwError, DWORD dwTrans, LPWSAOVERLAPPED lpOverlap, DWORD nFlags) { LP_PER_IO_OPERATION_DATA lpData = (LP_PER_IO_OPERATION_DATA)lpOverlap; if (0 != dwError) // 接收失败 { printf("Socket %d Close!\n", lpData->sClient); closesocket(lpData->sClient); HeapFree(GetProcessHeap(), 0, lpData); } else // 接收成功 { lpData->chMsg[dwTrans] = '\0'; send(lpData->sClient, lpData->chMsg, dwTrans, 0); printf("Socket:%d MSG: %s \n", lpData->sClient, lpData->chMsg); memset(&lpData->overLap, 0, sizeof(WSAOVERLAPPED)); lpData->wsaBuf.len = MSG_SIZE; lpData->wsaBuf.buf = lpData->chMsg; // 继续接收来自客户端的数据 实现 WSARecv与CompletionRoutine循环 WSARecv(lpData->sClient, &lpData->wsaBuf,1, &lpData->nRecvNum, &lpData->nFlags, &lpData->overLap, CompletionRoutine); } } int main() { WSADATA wsaData; WSAStartup(0x0202, &wsaData); SOCKET sListen; sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in addrListen; addrListen.sin_family = AF_INET; addrListen.sin_port = htons(PORT); addrListen.sin_addr.S_un.S_addr = htonl(ADDR_ANY); int nErrorCode = 0; nErrorCode = bind(sListen, (sockaddr*)&addrListen, sizeof(sockaddr)); nErrorCode = listen(sListen, 5); DWORD nThreadID; CreateThread(NULL, 0, workThread, NULL, 0, &nThreadID); sockaddr_in addrConnect; int nAddrLen = sizeof(sockaddr_in); printf("Server Started!\n"); while(TRUE) { g_sConnect= accept(sListen, (sockaddr*)&addrConnect, &nAddrLen); if (INVALID_SOCKET == g_sConnect) { return -1; } g_bConnect = true; // 连接成功 printf("Accept Client :%s -- PORT:%d\n", inet_ntoa(addrConnect.sin_addr), htons(addrConnect.sin_port)); } return 0; }
酷爱冰红茶
  • 粉丝: 0
上传资源 快速赚钱