Windows网络编程 — UDP完成端口的实现

在Winwos下共有5种I/O模型,可让Winsock应用程序对I/O进行管理,它们包括:

  select(选择); WSAAsyncSelect(异步选择模型);

      WSAEventSelect(事件选择模型);

      Overlapped(重叠);

      completion port(完成端口);

 

      以下记叙的是完成端口的实现步骤:(相关函数s参数说明,详见MSDN)

      1、使用函数HANDLE CreateIoCompletionPort(...)创建一个完成端口句柄;

      例:HANDLE hIocp=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);

 

      2、创建工作线程

 

  创建好完成端口后创建好工作线程。在第二步就创建工作线程是让完成端口处于准备工作的状态,一旦完成端口与套接字绑定后重叠后,并马上进行工作。这样做有益于程序的稳健性。工作线程的个数为 CPU个数*2+2 以便更好的发挥计算机的潜能,因为工作线程中某些工作可能处理挂起等待状态,这样资源便会被闲置。

   (创建工作线程的过程中注意维护好每个线程的句柄,以便使用WaitingForMultiObject来确保所有线程退出后释放各种资源。)

 

      3、创建一个套接字并绑定好地址和端口

 

      例: int port=6666;

       sockaddr_in localAddr={0};

       SOCKET iocpSocket=socket(AF_INET,SOCK_DGRAM,0);

       localAddr.family=AF_INET;

       localAddr.port=htons(port);

       localAddr.sin_addr.S_un.S_addr=INADDR_ANY;

           bind(iocpSocket,(sockaddr*)&localAddr,sizeof(sockaddr*));

 

      4、将套接字与完成端口绑定

 

      例: ULONG iocpKey=11; //与套接字关联的键

           HANDLE tmpHIocp=CreateIoCompletionPort((HANDLE)iocpSocket,hIocp,iocpKey,0); // 返回的HANDLE tmpIocp应与hIocp值一样;

 

     

      5.套接字重叠操作

    定义一个结构体(如:IOCPDATA),第一个一定要是WSAOVERLAPPED类型的成员,后面跟上WSARecvFrom中需要的参数作为成员(如:WSABUF,SOCKETADDR_IN,char *...等)。

 

    绑定完套接口后,立即对套接口重叠操作 (CPU个数*2+2) 次(与线程数一致);在每次重叠操作(WSARecvFrom)的之前 new 一个之前定义的结构体IOCPDATA(,并分配的结构体IOCP地址用list或其他该法维护起来以结束完成端口工作时作资源释放),将结构体IOCPDATA的指针强转成"LPWSAOVERLAPPED"附值给WSARecvFrom的第8个参数LPWSAOVERLAPPED lpOverlapped(IOCPDATA的各个成员变量的结果值会在工作线程中执行函数GetQueuedCompletionStatus后得到,即强转GetQueuedCompletionStatus的第4个参数LPOVERLAPPED* lpOverlapped的结果值为结构体指针(IOCPDATA *),这个值就是WSARecvFrom第8个参数的地址值)。

 

   使用函数int WSARecvFrom(...)执行重叠操作,重叠成功后函数返回值为SOCKET_ERROR,使用WSAGetLastError()的值为WSA_IO_PENDING;

 

  注意附给WSARecvFrom的第四个参数LPDWORD lpFlags变量应附值为0再取地址传递,否则重叠失败。

 

     6.结束完成端口

 

      使用PostQueuedCompletionStatus函数通知结束工作线程结束完成端口时,利用之前维护的线程句柄list(或其他容器)使用WaitForMultiObject函数来确保所有的工作线程全都退出,然后再释放各类资源(如socket,完成端口句柄,和各个重叠时的缓冲区);

 

 

(备注:之所以在工作线程外面先进行一次重叠操作这样可以有效的利用并管理各个线程工作时套接字接收数据时需要用到的数据缓冲区,还有避免一些复杂的线程安全问题,或且避免每次套接字接完数据delete掉缓冲区再new缓冲区所可能造成的内存碎片的问题)

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值