`

IOCP模型与网络编程

 
阅读更多
转自http://blog.csdn.net/neicole/article/details/7549497
IBM的一片文章http://www.ibm.com/developerworks/cn/java/j-lo-iocp/
DELPHI示例http://blog.csdn.net/sqldebug_fan/article/details/7881793


IOCP模型与网络编程
一。前言:
        在老师分配任务(“尝试利用IOCP模型写出服务端和客户端的代码”)给我时,脑子一片空白,并不知道什么是IOCP模型,会不会是像软件设计模式里面的工厂模式,装饰模式之类的那些呢?嘿嘿,不过好像是一个挺好玩的东西,挺好奇是什么东西来的,又是一个新知识啦~于是,开始去寻找一大堆的资料,为这个了解做准备,只是呢,有时还是想去找一本书去系统地学习一下,毕竟网络的资料还是有点零散。话说,本人学习这个模型的基础是,写过一个简单的Socket服务器及客户端程序,外加一个简单的Socket单服务器对多客户端程序,懂一点点的操作系统原理的知识。于是,本着一个学习与应用的态度开始探究这个IOCP是个什么东西。

二。提出相关问题:
       1.  IOCP模型是什么?
       2.  IOCP模型是用来解决什么问题的?它为什么存在?
       3.  使用IOCP模型需要用到哪些知识?
       4.  如何使用IOCP模型与Socket网络编程结合起来?
       5.  学会了这个模型以后与我之前写过的简单的socket程序主要有哪些不同点?

三。部分问题探究及解决:(绝大多数是个人理解,再加上个人是菜鸟,如果有什么不对的地方,欢迎指正)
       1.  什么是IOCP?什么是IOCP模型?IOCP模型有什么作用?
              1) IOCP(I/O Completion Port),常称I/O完成端口。
              2) IOCP模型属于一种通讯模型,适用于(能控制并发执行的)高负载服务器的一个技术。
              3) 通俗一点说,就是用于高效处理很多很多的客户端进行数据交换的一个模型。
              4) 或者可以说,就是能异步I/O操作的模型。
              5) 只是了解到这些会让人很糊涂,因为还是不知道它究意具体是个什么东东呢?

下面我想给大家看三个图:
第一个是IOCP的内部工作队列图。(整合于《IOCP本质论》文章,在英文的基础上加上中文对照)



第二个是程序实现IOCP模型的基本步骤。(整合于《深入解释IOCP》,加个人观点、理解、翻译)



第三个是使用了IOCP模型及没使用IOCP模型的程序流程图。(个人理解绘制)


2.  IOCP的存在理由(IOCP的优点)及技术相关有哪些?
        之前说过,很通俗地理解可以理解成是用于高效处理很多很多的客户端进行数据交换的一个模型,那么,它具体的优点有些什么呢?它到底用到了哪些技术了呢?在Windows环境下又如何去使用这些技术来编程呢?它主要使用上哪些API函数呢?呃~看来我真是一个问题多多的人,跟前面提出的相关问题变种延伸了不少的问题,好吧,下面一个个来解决。

1) 使用IOCP模型编程的优点
       ① 帮助维持重复使用的内存池。(与重叠I/O技术有关)
       ② 去除删除线程创建/终结负担。
       ③ 利于管理,分配线程,控制并发,最小化的线程上下文切换。
       ④ 优化线程调度,提高CPU和内存缓冲的命中率。
2) 使用IOCP模型编程汲及到的知识点(无先后顺序)
       ① 同步与异步
       ② 阻塞与非阻塞
       ③ 重叠I/O技术
       ④ 多线程
       ⑤ 栈、队列这两种基本的数据结构
3) 需要使用上的API函数
  ① 与SOCKET相关
       1、链接套接字动态链接库:int WSAStartup(...);
       2、创建套接字库:        SOCKET socket(...);
       3、绑字套接字:          int bind(...);
       4、套接字设为监听状态: int listen(...);
       5、接收套接字:          SOCKET accept(...);
       6、向指定套接字发送信息:int send(...);
       7、从指定套接字接收信息:int recv(...);
  ② 与线程相关
       1、创建线程:HANDLE CreateThread(...);
  ③ 重叠I/O技术相关
       1、向套接字发送数据:    int WSASend(...);
       2、向套接字发送数据包:  int WSASendFrom(...);
       3、从套接字接收数据:    int WSARecv(...);
       4、从套接字接收数据包:  int WSARecvFrom(...);
  ④ IOCP相关
       1、创建完成端口: HANDLE WINAPI CreateIoCompletionPort(...);
       2、关联完成端口: HANDLE WINAPI CreateIoCompletionPort(...);
       3、获取队列完成状态: BOOL WINAPI GetQueuedCompletionStatus(...);
       4、投递一个队列完成状态:BOOL WINAPI PostQueuedCompletionStatus(...);

四。完整的简单的IOCP服务器与客户端代码实例:


// IOCP_TCPIP_Socket_Server.cpp

#include <WinSock2.h>
#include <Windows.h>
#include <vector>
#include <iostream>

using namespace std;

#pragma comment(lib, "Ws2_32.lib")		// Socket编程需用的动态链接库
#pragma comment(lib, "Kernel32.lib")	// IOCP需要用到的动态链接库

/**
 * 结构体名称:PER_IO_DATA
 * 结构体功能:重叠I/O需要用到的结构体,临时记录IO数据
 **/
const int DataBuffSize  = 2 * 1024;
typedef struct
{
	OVERLAPPED overlapped;
	WSABUF databuff;
	char buffer[ DataBuffSize ];
	int BufferLen;
	int operationType;
}PER_IO_OPERATEION_DATA, *LPPER_IO_OPERATION_DATA, *LPPER_IO_DATA, PER_IO_DATA;

/**
 * 结构体名称:PER_HANDLE_DATA
 * 结构体存储:记录单个套接字的数据,包括了套接字的变量及套接字的对应的客户端的地址。
 * 结构体作用:当服务器连接上客户端时,信息存储到该结构体中,知道客户端的地址以便于回访。
 **/
typedef struct
{
	SOCKET socket;
	SOCKADDR_STORAGE ClientAddr;
}PER_HANDLE_DATA, *LPPER_HANDLE_DATA;

// 定义全局变量
const int DefaultPort = 6000;		
vector < PER_HANDLE_DATA* > clientGroup;		// 记录客户端的向量组

HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);
DWORD WINAPI ServerWorkThread(LPVOID CompletionPortID);
DWORD WINAPI ServerSendThread(LPVOID IpParam);

// 开始主函数
int main()
{
// 加载socket动态链接库
	WORD wVersionRequested = MAKEWORD(2, 2); // 请求2.2版本的WinSock库
	WSADATA wsaData;	// 接收Windows Socket的结构信息
	DWORD err = WSAStartup(wVersionRequested, &wsaData);

	if (0 != err){	// 检查套接字库是否申请成功
		cerr << "Request Windows Socket Library Error!\n";
		system("pause");
		return -1;
	}
	if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2){// 检查是否申请了所需版本的套接字库
		WSACleanup();
		cerr << "Request Windows Socket Version 2.2 Error!\n";
		system("pause");
		return -1;
	}

// 创建IOCP的内核对象
	/**
	 * 需要用到的函数的原型:
	 * HANDLE WINAPI CreateIoCompletionPort(
     *    __in   HANDLE FileHandle,		// 已经打开的文件句柄或者空句柄,一般是客户端的句柄
     *    __in   HANDLE ExistingCompletionPort,	// 已经存在的IOCP句柄
     *    __in   ULONG_PTR CompletionKey,	// 完成键,包含了指定I/O完成包的指定文件
     *    __in   DWORD NumberOfConcurrentThreads // 真正并发同时执行最大线程数,一般推介是CPU核心数*2
     * );
	 **/
	HANDLE completionPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 0);
	if (NULL == completionPort){	// 创建IO内核对象失败
		cerr << "CreateIoCompletionPort failed. Error:" << GetLastError() << endl;
		system("pause");
		return -1;
	}

// 创建IOCP线程--线程里面创建线程池

	// 确定处理器的核心数量
	SYSTEM_INFO mySysInfo;
	GetSystemInfo(&mySysInfo);

	// 基于处理器的核心数量创建线程
	for(DWORD i = 0; i < (mySysInfo.dwNumberOfProcessors * 2); ++i){
		// 创建服务器工作器线程,并将完成端口传递到该线程
		HANDLE ThreadHandle = CreateThread(NULL, 0, ServerWorkThread, completionPort, 0, NULL);
		if(NULL == ThreadHandle){
			cerr << "Create Thread Handle failed. Error:" << GetLastError() << endl;
		system("pause");
			return -1;
		}
		CloseHandle(ThreadHandle);
	}

// 建立流式套接字
	SOCKET srvSocket = socket(AF_INET, SOCK_STREAM, 0);

// 绑定SOCKET到本机
	SOCKADDR_IN srvAddr;
	srvAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	srvAddr.sin_family = AF_INET;
	srvAddr.sin_port = htons(DefaultPort);
	int bindResult = bind(srvSocket, (SOCKADDR*)&srvAddr, sizeof(SOCKADDR));
	if(SOCKET_ERROR == bindResult){
		cerr << "Bind failed. Error:" << GetLastError() << endl;
		system("pause");
		return -1;
	}

// 将SOCKET设置为监听模式
	int listenResult = listen(srvSocket, 10);
	if(SOCKET_ERROR == listenResult){
		cerr << "Listen failed. Error: " << GetLastError() << endl;
		system("pause");
		return -1;
	}
	
// 开始处理IO数据
	cout << "本服务器已准备就绪,正在等待客户端的接入...\n";

	// 创建用于发送数据的线程
	HANDLE sendThread = CreateThread(NULL, 0, ServerSendThread, 0, 0, NULL);

	while(true){
		PER_HANDLE_DATA * PerHandleData = NULL;
		SOCKADDR_IN saRemote;
		int RemoteLen;
		SOCKET acceptSocket;

		// 接收连接,并分配完成端,这儿可以用AcceptEx()
		RemoteLen = sizeof(saRemote);
		acceptSocket = accept(srvSocket, (SOCKADDR*)&saRemote, &RemoteLen);
		if(SOCKET_ERROR == acceptSocket){	// 接收客户端失败
			cerr << "Accept Socket Error: " << GetLastError() << endl;
			system("pause");
			return -1;
		}
		
		// 创建用来和套接字关联的单句柄数据信息结构
		PerHandleData = (LPPER_HANDLE_DATA)GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA));	// 在堆中为这个PerHandleData申请指定大小的内存
		PerHandleData -> socket = acceptSocket;
		memcpy (&PerHandleData -> ClientAddr, &saRemote, RemoteLen);
		clientGroup.push_back(PerHandleData);		// 将单个客户端数据指针放到客户端组中

		// 将接受套接字和完成端口关联
		CreateIoCompletionPort((HANDLE)(PerHandleData -> socket), completionPort, (DWORD)PerHandleData, 0);

		
		// 开始在接受套接字上处理I/O使用重叠I/O机制
		// 在新建的套接字上投递一个或多个异步
		// WSARecv或WSASend请求,这些I/O请求完成后,工作者线程会为I/O请求提供服务	
		// 单I/O操作数据(I/O重叠)
		LPPER_IO_OPERATION_DATA PerIoData = NULL;
		PerIoData = (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_OPERATEION_DATA));
		ZeroMemory(&(PerIoData -> overlapped), sizeof(OVERLAPPED));
		PerIoData->databuff.len = 1024;
		PerIoData->databuff.buf = PerIoData->buffer;
		PerIoData->operationType = 0;	// read

		DWORD RecvBytes;
		DWORD Flags = 0;
		WSARecv(PerHandleData->socket, &(PerIoData->databuff), 1, &RecvBytes, &Flags, &(PerIoData->overlapped), NULL);
	}

	system("pause");
	return 0;
}

// 开始服务工作线程函数
DWORD WINAPI ServerWorkThread(LPVOID IpParam)
{
	HANDLE CompletionPort = (HANDLE)IpParam;
	DWORD BytesTransferred;
	LPOVERLAPPED IpOverlapped;
	LPPER_HANDLE_DATA PerHandleData = NULL;
	LPPER_IO_DATA PerIoData = NULL;
	DWORD RecvBytes;
	DWORD Flags = 0;
	BOOL bRet = false;

	while(true){
		bRet = GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (PULONG_PTR)&PerHandleData, (LPOVERLAPPED*)&IpOverlapped, INFINITE);
		if(bRet == 0){
			cerr << "GetQueuedCompletionStatus Error: " << GetLastError() << endl;
			return -1;
		}
		PerIoData = (LPPER_IO_DATA)CONTAINING_RECORD(IpOverlapped, PER_IO_DATA, overlapped);
		
		// 检查在套接字上是否有错误发生
		if(0 == BytesTransferred){
			closesocket(PerHandleData->socket);
			GlobalFree(PerHandleData);
			GlobalFree(PerIoData);
			continue;
		}
		
		// 开始数据处理,接收来自客户端的数据
		WaitForSingleObject(hMutex,INFINITE);
		cout << "A Client says: " << PerIoData->databuff.buf << endl;
		ReleaseMutex(hMutex);

		// 为下一个重叠调用建立单I/O操作数据
		ZeroMemory(&(PerIoData->overlapped), sizeof(OVERLAPPED)); // 清空内存
		PerIoData->databuff.len = 1024;
		PerIoData->databuff.buf = PerIoData->buffer;
		PerIoData->operationType = 0;	// read
		WSARecv(PerHandleData->socket, &(PerIoData->databuff), 1, &RecvBytes, &Flags, &(PerIoData->overlapped), NULL);
	}

	return 0;
}


// 发送信息的线程执行函数
DWORD WINAPI ServerSendThread(LPVOID IpParam)
{
	while(1){
		char talk[200];
		gets(talk);
		int len;
		for (len = 0; talk[len] != '\0'; ++len){
			// 找出这个字符组的长度
		}
		talk[len] = '\n';
		talk[++len] = '\0';
		printf("I Say:");
		cout << talk;
		WaitForSingleObject(hMutex,INFINITE);
		for(int i = 0; i < clientGroup.size(); ++i){
			send(clientGroup[i]->socket, talk, 200, 0);	// 发送信息
		}
		ReleaseMutex(hMutex); 
	}
	return 0;
}


// IOCP_TCPIP_Socket_Client.cpp

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <winsock2.h>
#include <Windows.h>

using namespace std;

#pragma comment(lib, "Ws2_32.lib")		// Socket编程需用的动态链接库

SOCKET sockClient;		// 连接成功后的套接字
HANDLE bufferMutex;		// 令其能互斥成功正常通信的信号量句柄
const int DefaultPort = 6000;

int main()
{
// 加载socket动态链接库(dll)
	WORD wVersionRequested;
	WSADATA wsaData;	// 这结构是用于接收Wjndows Socket的结构信息的
	wVersionRequested = MAKEWORD( 2, 2 );	// 请求2.2版本的WinSock库
	int err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {	// 返回值为零的时候是表示成功申请WSAStartup
		return -1;
	}
	if ( LOBYTE( wsaData.wVersion ) != 2 ||	HIBYTE( wsaData.wVersion ) != 2 ) { // 检查版本号是否正确
		WSACleanup( );
		return -1; 
	}
	
// 创建socket操作,建立流式套接字,返回套接字号sockClient
	 sockClient = socket(AF_INET, SOCK_STREAM, 0);
	 if(sockClient == INVALID_SOCKET) { 
		printf("Error at socket():%ld\n", WSAGetLastError()); 
        WSACleanup(); 
        return -1; 
      } 

// 将套接字sockClient与远程主机相连
	// int connect( SOCKET s,  const struct sockaddr* name,  int namelen);
	// 第一个参数:需要进行连接操作的套接字
	// 第二个参数:设定所需要连接的地址信息
	// 第三个参数:地址的长度
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");		// 本地回路地址是127.0.0.1; 
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(DefaultPort);
	while(SOCKET_ERROR == connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR))){
		// 如果还没连接上服务器则要求重连
		cout << "服务器连接失败,是否重新连接?(Y/N):";
		char choice;
		while(cin >> choice && (!((choice != 'Y' && choice == 'N') || (choice == 'Y' && choice != 'N')))){
			cout << "输入错误,请重新输入:";
			cin.sync();
			cin.clear();
		}
		if (choice == 'Y'){
			continue;
		}
		else{
			cout << "退出系统中...";
			system("pause");
			return 0;
		}
	}
	cin.sync();
	cout << "本客户端已准备就绪,用户可直接输入文字向服务器反馈信息。\n";

	send(sockClient, "\nAttention: A Client has enter...\n", 200, 0);

	bufferMutex = CreateSemaphore(NULL, 1, 1, NULL); 

	DWORD WINAPI SendMessageThread(LPVOID IpParameter);
	DWORD WINAPI ReceiveMessageThread(LPVOID IpParameter);

	HANDLE sendThread = CreateThread(NULL, 0, SendMessageThread, NULL, 0, NULL);  
	HANDLE receiveThread = CreateThread(NULL, 0, ReceiveMessageThread, NULL, 0, NULL);  

	   
    WaitForSingleObject(sendThread, INFINITE);  // 等待线程结束
	closesocket(sockClient);
	CloseHandle(sendThread);
	CloseHandle(receiveThread);
	CloseHandle(bufferMutex);
	WSACleanup();	// 终止对套接字库的使用

	printf("End linking...\n");
	printf("\n");
	system("pause");
	return 0;
}


DWORD WINAPI SendMessageThread(LPVOID IpParameter)
{
	while(1){
		string talk;
		getline(cin, talk);
		WaitForSingleObject(bufferMutex, INFINITE);		// P(资源未被占用)  
		if("quit" == talk){
			talk.push_back('\0');
			send(sockClient, talk.c_str(), 200, 0);
			break;
		}
		else{
			talk.append("\n");
		}
		printf("\nI Say:(\"quit\"to exit):");
		cout << talk;
		send(sockClient, talk.c_str(), 200, 0);	// 发送信息
		ReleaseSemaphore(bufferMutex, 1, NULL);		// V(资源占用完毕) 
	}
	return 0;
}


DWORD WINAPI ReceiveMessageThread(LPVOID IpParameter)
{
	while(1){	
		char recvBuf[300];
		recv(sockClient, recvBuf, 200, 0);
		WaitForSingleObject(bufferMutex, INFINITE);		// P(资源未被占用)  

		printf("%s Says: %s", "Server", recvBuf);		// 接收信息
		
		ReleaseSemaphore(bufferMutex, 1, NULL);		// V(资源占用完毕) 
	}
	return 0;
}


五。本次学习资料
       几翻周折,终于写出一个比较简单的IOCP模型的服务器与客户端啦,并且也大概了解这个模型的思路啦~没有买书的娃,伤不起啊,只能从网上搜罗资料,幸好有这些文章在,最后为下列这些文章的作者说声谢谢~
分享到:
评论

相关推荐

    介绍iocp模型的一般编程流程

    在实际编程中,你可以利用IOCP模型来设计高效的服务器应用,例如网络服务器,通过复用线程处理大量的并发连接。通过合理调度工作线程,可以保证系统在高负载下仍然能保持良好的性能。 在"www.pudn.com.txt"和"IOCP...

    VC++网络编程IOCP网络模型(源码)

    6. **Overlapped I/O**:IOCP模型通常与重叠I/O配合使用,允许I/O操作在后台进行,而不会阻塞主线程。 7. **线程池**:为了有效地处理来自IOCP的通知,通常会使用线程池。当一个I/O操作完成时,线程池会自动分配一...

    一个简单的IOCP模型的服务器

    通过这个简单的IOCP模型服务器,我们可以学习到如何在高并发场景下构建高效的网络服务。IOCP模型不仅可以用于TCP连接,也可以应用于UDP等其他I/O操作。同时,理解并掌握IOCP模型对于深入理解Windows系统底层的I/O...

    C# IOCP完成端口模型(简单实用高效)

    在TCP网络编程中,IOCP模型可以很好地处理大量并发连接。每当有新的TCP连接请求到达,服务器可以创建一个新的套接字,将其关联到完成端口,然后接收和发送数据。由于IOCP的非阻塞特性,即使有很多并发连接,服务器也...

    IOCP模型实例(完成端口模型)

    但需要注意的是,IOCP模型的编程相对复杂,需要对Windows底层I/O机制有深入了解,且错误处理和调试难度较大。在实际应用中,开发者通常会借助第三方库如libevent、libev或Boost.Asio等简化开发工作。

    c++ IOCP模型服务端

    总的来说,C++的IOCP模型服务端开发是一项涉及多方面技术的工作,包括网络编程、多线程、异步I/O、错误处理和性能优化等。理解并熟练掌握这些知识点,才能构建出稳定、高效的服务器应用程序。在"LYServer"这个项目中...

    IOCP模型 ,最高效的socket模型 海量套接字连接首选

    IOCP(I/O Completion Port,I/O完成端口)模型是Windows操作系统中一种高效处理大量并发I/O操作的机制,特别适用于需要...然而,理解和实现IOCP模型需要深入理解操作系统内核的I/O机制,以及良好的多线程编程技巧。

    IOCP 模型学习总结代码

    它主要用于网络编程,特别是在服务器端,能够有效地处理来自多个客户端的并发请求,实现高度并发且线程利用率高的服务。下面是对IOCP模型的详细解释及其在实战中的应用。 1. IOCP的基本概念: I/O完成端口是一种多...

    IOCP模型客户端服务端demo

    总之,IOCP模型是高性能服务器开发中的重要技术,它能够有效地处理大规模并发连接,对于理解和实践网络服务器的优化有极大的帮助。这个C++实现的IOCP客户端服务端示例,将是你学习这一关键技术的良好起点。

    IOCP网络编程

    IOCP(I/O Completion Port,I/O 完成端口)是 Windows 操作系统提供的一种高效、可扩展的网络编程模型,尤其适用于处理大量并发连接请求。在C++中实现IOCP网络编程,可以构建高性能的服务器应用,尤其是在TCP/IP...

    【Select模型】VS【IOCP模型】处理能力试验报告

    **【Select模型】与【IOCP模型】是两种在多路复用技术中常见的网络编程模型,用于处理并发的I/O操作。这两种模型各有特点,适用于不同的场景。本文通过一个原创的试验报告,对比了它们在UDP数据处理能力上的表现。**...

    windows socket网络编程之iocp完成端口模型的例子

    IOCP在许多高性能网络服务中得到广泛应用,例如Microsoft IIS(Internet Information Services)就使用了IOCP模型来处理HTTP请求。在编写高并发、低延迟的网络应用时,IOCP是一个值得考虑的技术选择。 总结来说,...

    mfc 网络编程iocp实例

    本文将深入探讨MFC网络编程中的一个重要概念——IOCP(I/O完成端口),并结合提供的"mfc 网络编程iocp实例"进行详细解析。 IOCP(I/O完成端口)是Windows操作系统内核提供的一种高效、可扩展的I/O模型,特别适用于...

    winsock网络通信(select和IOCP模型,客户端和服务器都有)

    总之,select和IOCP模型在客户端和服务器的网络通信中扮演着重要角色。选择哪种模型取决于应用的需求,如并发连接数、系统资源、性能要求以及开发环境。理解这两种模型的工作原理,以及如何在实际项目中应用它们,...

    IOCP模型远控源码

    在“IOCP模型远控源码(过360通信拦截)”这个项目中,我们可以推测这是一套利用IOCP模型实现的远程控制程序,并且通过特定的技术手段绕过了360安全软件的通信拦截。 IOCP的核心思想是将I/O操作与处理I/O完成的任务...

    Iocp模型服务器qt工程(内含源码、压力测试客户端)

    标题中的"Iocp模型服务器qt工程"涉及到两个关键概念:IO完成端口(I/O Completion Ports, I/OCP)和Qt。I/OCP是Windows操作系统中的一种高效处理大量并发I/O请求的技术,而Qt则是一个跨平台的C++图形用户界面库。 ...

    vc以IOCP完成端口方式实现网络数据传输 iocp服务器+客户端.zip

    Socket是网络通信的基础,而在IOCP模型中,我们可以将socket与完成端口关联起来。这样,socket上的所有读写操作都会通过完成端口返回结果,而非阻塞在调用上。 4. Server端实现: - 同步Accept:描述中提到服务器...

    MFC IOCP模型异步IO

    通过学习"MFC IOCP模型异步IO",你可以掌握如何在Windows环境中利用MFC高效地处理并发I/O操作,这对于开发服务器软件、网络应用或者需要大量磁盘读写的应用来说是非常有价值的。IOCP的使用可以显著提高系统的响应...

    net-iocp.rar_.net IOCP_IOCP_IOCP windows_Windows iocp使用_iocp编程

    .NET IOCP(I/O完成端口)是Windows操作系统中一种高效、异步的网络I/O模型,用于处理大量并发的网络连接。IOCP(Input/Output Completion Port)在Windows系统中提供了一种线程池机制,它允许应用程序通过一个单一...

    arcemu魔兽私服网络引擎源码

    二、IOCP模型与网络编程 arcemu采用了Windows的I/O完成端口(IOCP,Input/Output Completion Port)模型进行网络通信。IOCP是一种高效的异步I/O模型,可以处理大量的并发连接,这正是网络游戏服务器所需的。理解...

Global site tag (gtag.js) - Google Analytics