Socket通讯 完成端口 怎么实现同时收发
2015-06-09 10:32
330 查看
如果大家对完成端口不熟悉,请先百度一下,详细的资料很多,这里主要是针对 采用 完成端口的SOCKET如果实现同时异步收发的进阶篇,由于之前在网上查找资料后发现对于这方面的相关资料甚少,于是在此留文。
你需要熟悉如下函数才能理解此文: CreateIoCompletionPort,GetQueuedCompletionStatus,WSARecvForm,WSASendTo
这里是以UDP的通讯为设计前提,TCP的大同小异。
废话少说,直接进主题:
HANDLE WINAPI CreateIoCompletionPort( _In_ HANDLE FileHandle, _In_opt_ HANDLE ExistingCompletionPort, _In_ ULONG_PTR CompletionKey, _In_ DWORD NumberOfConcurrentThreads );
完成端口在创建时需要传入CompletionKey,这个Key是在创建时传入的,由用户自定义,(可能指向一个结构体),我们再来看看下面的取结果函数
BOOL WINAPI GetQueuedCompletionStatus( _In_ HANDLE CompletionPort, _Out_ LPDWORD lpNumberOfBytes, _Out_ PULONG_PTR lpCompletionKey, _Out_ LPOVERLAPPED *lpOverlapped, _In_ DWORD dwMilliseconds );
这个 lpCompletionKey
的函数就是取创建时传入的值,我们可以在里面存放对应的socket地址等数据, 但我们是没办法分清到底是那一次的发送和接收数据完成了(最理想的状态是GetQueuedCompletionStatus函数中能返回我们每一次发送接收的数据包地址),所以造成在网上很多人都是采用单纯的异步接收,而发送只能用同步的方式,在这个基础上我提出一种进阶的方法:
看看这个函数中有一个OverLapped的结构体,经过测试,这个结构体返回的地址刚好就是我们调用 WSARecvForm 或WSASendto中传入的OverLapp的地址
因此只要我们在调用WSASendTo和WSARecvForm时记录下该OverLapp的地址到链表,那样在GetQueuedCompletionStatus完成时就可以进行对比确定哪个数据包已经发送成功。
相关文章推荐
- Windows多线程通信
- 登录界面
- 公司来了位傻员工
- Select函数实现原理分析
- Restore IP Addresses
- 【剑指offer】 面试题6: 重建二叉树
- linephone-3.8.2运行结果
- Linux小技巧记录
- “.网络”域名6月初市场报告:新网冠军 万网亚军
- FatJar for Eclipse4.4(Luna)
- Oracle 检查表的数据变动
- Ueeshop:外贸网站报价,从免费到数十万是怎么回事?
- Linux chkconfig命令入门
- SQL Server delete、truncate、drop
- java入门
- java定义和实现接口
- 如何在 Ubuntu 14.04 里面配置 chroot 环境
- C语言之忽略SIGPIPE信号
- Shell脚本编程初体验
- SqlParameter数组