socket通讯IOCP模型

1.同步与异步模式(Sync/Async)
在一些IO函数如ReadFile(),socket.recv(),默认使用的是同步模式,即函数执行完成后才返回,如果既没有数据,也没有超时设置,则程序会阻塞在这里。在对话框主程序中,如果使用这种方式会把界面卡死。

处理这类问题的常见方法是,启动一个线程,将这些IO操作放在线程中执行。如果需要结束线程的阻塞状态,只要在主线程中关闭Handle/Socket即可。

另一种处理方式为异步模式,IO函数ReadFile()调用后直接返回,通过查询状态来获取其执行结果,如:
HANDLE hFile = CreateFile(xx, GENERIC_READ, 0, NULL,...,FILE_FLAG_OVERLAPPED); //指定FILE_FLAG_OVERLAPPED
OVERLAPPED overlap;
ReadFile(hFile, buf,nsize, &nread, &overlap);//立即返回false,err=IO_PENDING
while(i<100 && !HasOverlappedIoCompleted(&overlap)); // 等待完成……
{ DoSomething();
  i++;Sleep(1000);//CancelIO(hFile)...
}
这种方式可以对阻塞过程进行控制,如超时退出或做其他处理。

2.同步模式的多任务
以上两种模式,在单个IO操作时区别不大,异步模式更零活一些。在多任务的情况下,网络服务器面向上万的客户端,同步模式则需要开启上万个线程来通讯
sockServer = socket(...);
_beginThread(Thread_Recving, ...);
Thread_Accepting()
{
  while(bRunning)
  {
    sockClient = accept(sockServer, ...); //blocking
    _beginThread(Thread_Recving, ...);
  }
}
Thread_Recving() // 10000+个线程
{
  while(bRunning)
  {
    recv(sockClient, ...); //blocking
    DoSomthing();
  }
}
这种方式非常消耗CPU和内存资源,系统在各个线程之间切换,效率很低。

3.异步模式的多任务——IOCP
在上面的例子中,如果以异步模式建立连接,以轮询的方式来检查各个连接是否收到数据
sockServer = socket(...);
_beginthread(Thread_Accepting, ...);
_beginthread(Thread_Recving, ...);
Thread_Accepting()
{
  while(bRunning)
  {
    sockClient[x] = accept(sockServer, ...); //non-blocking
    recv(sockClient[x], &overlap[x]);
  }
}
Thread_Recving()
{
  while(bRunning)
  {
    for(i=0; i<10000; i++)
    {
      if(HasOverlappedIoCompleted(&overlap[i]))
        DoSomthing(i);
    }
  }
}
这种方式显然不可行,并发的时候,单个线程处理,如果DoSomthing(i)处理时间长,则很容易造成数据丢失未处理。
这种情况下,比较好的方法是IOCP(Complete Port).IIS,FTP等许多网络服务器软件,都是采用这种模式。首先根据CPU数量来建立线程连接池,可以利用网卡DMA等特性,直接将网络数据写入内存,再动态调用线程来处理数据。

WSAStartup(MAKEWORD(2, 2), &wsaData); // WinSock 2.2
hCompPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

sockSvr = socket(AF_INET, SOCK_STREAM, 0);
bind(m_sockSvr, (SOCKADDR*)&srvAddr, sizeof(SOCKADDR));
listen(m_sockSvr, 10);

CreateThread(Thread_Accepting, ...);
GetSystemInfo(&sysInfo);
for(i=0; i<sysInfo.dwNumberOfProcessors*2+2; i++)
  hThread[i] = CreateThread(NULL, 0, Thread_Recving, param, 0, NULL);

Thread_Accepting()
{
  while(bRunning)
  {
    sockClient[x] = accept(sockServer, ...); //non-blocking
    CreateIoCompletionPort(sockClient[x], hCompPort, param[x], 0); // 将IO对象sockClient[x]与hCompPort关联
    WSARecv(sockClient, wsaBuf, 1, &dwSize, &dwFlag, &overLapped, NULL); //non-blocking
  }
}
Thread_Recving() // 4*2+2=10个线程
{
  while(bRunning)
  {
    GetQueuedCompletionStatus(hCompPort, &dwRecv, param, &pOverlap, INFINITE); //blocking
    DoSomthing(wsaBuf); // 数据已经接收进了内存
    WSARecv(sock, &wsaBuf, 1, &dwRecv, &dwFlag, &overLap, NULL); // continue recving
  }
}
这种方式的好处是,恰好利用了全部CPU的资源,因为启动太多线程没有意义,反而耗费资源进行线程切换。

时间: 2024-11-10 14:46:51

socket通讯IOCP模型的相关文章

【IOCP】 IOCP模型属于一种通讯模型- 较难

http://baike.baidu.com/link?url=e9vXkKd2aHp8VDr1XTURdwQB4K85r28IYjeMwRIyuaXtsrCsXHY1eohiFgsDXRYRlj6xEQoZFzH9dgKwla2n3q IOCP(I/O Completion Port),常称I/O完成端口. IOCP模型属于一种通讯模型,适用于(能控制并发执行的)高负载服务器的一个技术. 通俗一点说,就是用于高效处理很多很多的客户端进行数据交换的一个模型.或者可以说,就是能异步I/O操作的模型

IOCP模型与网络编

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

IOCP模型与网络编程

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

IOCP模型、EPOLL模型的比较以及游戏服务器端的一些建议

一:IOCP和Epoll之间的异同.异:1:IOCP是WINDOWS系统下使用.Epoll是Linux系统下使用.2:IOCP是IO操作完毕之后,通过Get函数获得一个完成的事件通知.Epoll是当你希望进行一个IO操作时,向Epoll查询是否可读或者可写,若处于可读或可写状态后,Epoll会通过epoll_wait进行通知.3:IOCP封装了异步的消息事件的通知机制,同时封装了部分IO操作.但Epoll仅仅封装了一个异步事件的通知机制,并不负责IO读写操作.Epoll保持了事件通知和IO操作间

Nginx源码分析 - Nginx启动以及IOCP模型

Nginx 源码分析 - Nginx启动以及IOCP模型 版本及平台信息 本文档针对Nginx1.11.7版本,分析Windows下的相关代码,虽然服务器可能用linux更多,但是windows平台下的代码也基本相似 ,另外windows的IOCP完成端口,异步IO模型非常优秀,很值得一看. Nginx启动 曾经有朋友问我,面对一个大项目的源代码,应该从何读起呢?我给他举了一个例子,我们学校大一大二是在紫金港校区,到了 大三搬到玉泉校区,但是大一的时候也会有时候有事情要去玉泉办.偶尔会去玉泉,但

基于Delphi的Socket I/O模型全接触 good

老陈有一个在外地工作的女儿,不能经常回来,老陈和她通过信件联系.他们的信会被邮递员投递到他们的信箱里. 这和Socket模型非常类似.下面我就以老陈接收信件为例讲解Socket I/O模型. 一:select模型 老陈非常想看到女儿的信.以至于他每隔10分钟就下楼检查信箱,看是否有女儿的信,在这种情况下,“下楼检查信箱”然后回到楼上耽误了老陈太多的时间,以至于老陈无法做其他工作. select模型和老陈的这种情况非常相似:周而复始地去检查......如果有数据......接收/发送.......

IOCP模型总结(总结回顾)

IOCP旧代码重提,最近一直在玩其他方面的东东,时不时回顾一下,收益多多. IOCP(I/O Completion Port,I/O完成端口)是性能最好的一种I/O模型.它是应用程序使用线程池处理异步I/O请求的一种机制.在处理多个并发的异步I/O请求时,以往的模型都是在接收请求是创建一个线程来应答请求.这样就有很多的线程并行地运行在系统中.而这些线程都是可运行的,Windows内核花费大量的时间在进行线程的上下文切换,并没有多少时间花在线程运行上.再加上创建新线程的开销比较大,所以造成了效率的

Window下高性能IOCP模型队列多线程下应用

IOCP,先从概念上认识一下.IOCP全称I/O Completion Port,中文译为I/O完成端口.是Windows平台最高效的I/O模块,现在IIS服务器,就采用IOCP模型.IOCP是一个异步I/O的API,它可以高效地将I/O事件通知给应用程序.与使用select()或是其它异步方法不同的是,现在很多书,文字都直接将IOCP模块和网络编程关联起来,好像IOCP就是和网络打交道的.典型的IOCP模型的使用,是 将一个套接字(socket)与一个完成端口关联了起来,当一个网络事件发生的时

Windows Socket I/O模型

老陈有一个在外地工作的女儿,不能经常回来,老陈和她通过信件联系.他们的信会被邮递员投递到他们的信箱里.这和Socket模型非常类似.下面我就以老陈接收信件为例讲解Socket I/O模型~~~ 一:select模型 老陈非常想看到女儿的信.以至于他每隔10分钟就下楼检查信箱,看是否有女儿的信~~~~~在这种情况下,"下楼检查信箱"然后回到楼上耽误了老陈太多的时间,以至于老陈无法做其他工作.select模型和老陈的这种情况非常相似:周而复始地去检查......如果有数据......接收/