完毕port模型
完毕port模型过程例如以下:
1.调用CreateIoCompletionPort函数创建完毕port。
HANDLE CompletionPort=CreateIoCompletionStatus(INVALID_HANDLE_VALUE,NULL,0,0);
2.创建和处理器数目相等的工作线程
SYSTEM_INFO SysInfo;
GetSystemInfo(&SysInfo);
for(int i=0;i<SysInfo.)
for(int i=0;i<(sysInfo.dwNumberOfProcessors);i++)
{ HANDLE ThreadHandle=(HANDLE)_beginthreadex(NULL,0,CompletionPortProcessor,ComplPort,0,NULL); CloseHandle(ThreadHandle);
}
3.接受客服端连接请求,创建单句柄数据,调用CreateIoCompletionPort将客服端套接字绑定到完毕port上。
单据句柄数据结构能够自定义字段:
struct PTR_HANDLE_DATA
{//字段能够任意定义
SOCKET s;
int i;
}
将套接字绑定到完毕port上:
CreateIoCompletionPort(sClient,CompletionPort,(DWORD)PerHandleData,0);
4.创建单I/O数据。并将单I/O数据作为參数传递给重叠I/O函数:WSARecv、WSASend.
创建单I/O数据,该字段除了第一个字段必须为重叠结构OVERLAPPED外。其它字段能够自定义:
<pre class="cpp" name="code">struct PER_IO_DATA
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
char Buffer[DATA_BUFFER];
int OperationType;
};
调用重叠I/O函数:
WSARecv(PerHandleData->socket, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
5.在工作线程中,调用GetQueuedCompletionStatus函数等待完毕port的完毕请求。
GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (LPDWORD)&PerHandleData, (LPOVERLAPPED*)&PerIoData, INFINITE))
6.等待成功后,对请求处理。假设须要再次投递一个重叠I/O。
一个简单的样例例如以下
#include <WinSock2.h>
#include <stdio.h>
#include <string.h>
#include <ws2tcpip.h>
#include <process.h>
#pragma comment(lib, "ws2_32.lib ") //linking to the library
#define DATA_BUFFER 4*1024
#define RECV_OPERATION 1
#define SEND_OPERATION 2 struct PTR_HANDLE_DATA
{
SOCKET socket;
int Location;
};
struct PER_IO_DATA
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
char Buffer[DATA_BUFFER];
int OperationType;
};
unsigned int WINAPI CompletionPortProcessor(PVOID lParam)
{
HANDLE CompletionPort = (HANDLE)lParam;
DWORD BytesTransferred;
PTR_HANDLE_DATA *PerHandleData;
PER_IO_DATA *PerIoData; while(true)
{ if(0 == GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (LPDWORD)&PerHandleData, (LPOVERLAPPED*)&PerIoData, INFINITE))
{
if( (GetLastError() == WAIT_TIMEOUT) || (GetLastError() == ERROR_NETNAME_DELETED) )
{
closesocket(PerHandleData->socket); delete PerIoData;
delete PerHandleData;
continue;
}
return 0;
} // 说明client已经退出
if(BytesTransferred == 0)
{
closesocket(PerHandleData->socket);
delete PerIoData;
delete PerHandleData;
continue;
}
if(PerIoData->OperationType==RECV_OPERATION)
{
printf("%d:%s\n",PerHandleData->Location,PerIoData->DataBuf.buf);
// 继续向 socket 投递WSARecv操作
DWORD Flags = 0;
DWORD dwRecv = 0;
ZeroMemory(PerIoData, sizeof(PER_IO_DATA));
PerIoData->DataBuf.buf = PerIoData->Buffer;
PerIoData->DataBuf.len = DATA_BUFFER;
PerIoData->OperationType=RECV_OPERATION;
WSARecv(PerHandleData->socket, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
}
} return 0;
} void main()
{
HANDLE ComplPort;
ComplPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0); SYSTEM_INFO sysInfo;
memset(&sysInfo,0,sizeof(sysInfo));
GetSystemInfo(&sysInfo);
HANDLE *handleArray=(HANDLE *)malloc(sysInfo.dwNumberOfProcessors *sizeof(HANDLE));
for(int i=0;i<(sysInfo.dwNumberOfProcessors);i++)
{
handleArray[i]=(HANDLE)_beginthreadex(NULL,0,CompletionPortProcessor,ComplPort,0,NULL);
}
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2),&wsaData); SOCKET s,sClient;
struct addrinfo hints,*result;
int rc;
memset(&hints,0,sizeof(hints));
hints.ai_flags=AI_NUMERICHOST;//nodename is ip address;if set AI_PASSIVE ,it is computer name;if set AI_CANONNAME ,it is ..
hints.ai_family=AF_UNSPEC;//IPv4 OR IPv6;if IPv4,Set AF_INET; if IPv6,Set AF_INET6
hints.ai_socktype=SOCK_STREAM;//SOCK_DRGAM
hints.ai_protocol=IPPROTO_TCP;
rc=getaddrinfo("127.0.0.1","5001",&hints,&result);
s=socket(result->ai_family,result->ai_socktype,result->ai_protocol);
bind(s,result->ai_addr,result->ai_addrlen);
listen(s,5);
PER_IO_DATA *PerIoData;
PTR_HANDLE_DATA *PerHandleData;
int i=1;
while(true)
{
sClient = accept(s, 0,0);
PerHandleData = new PTR_HANDLE_DATA();
PerHandleData->socket = sClient;
PerHandleData->Location=i;
CreateIoCompletionPort((HANDLE)PerHandleData->socket, ComplPort, (DWORD)PerHandleData, 0); PerIoData = new PER_IO_DATA();
ZeroMemory(PerIoData, sizeof(PER_IO_DATA));
PerIoData->DataBuf.buf = PerIoData->Buffer;
PerIoData->DataBuf.len =DATA_BUFFER;
PerIoData->OperationType=RECV_OPERATION; DWORD Flags = 0;
DWORD dwRecv = 0;
WSARecv(PerHandleData->socket, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
i++;
} DWORD dwByteTrans;
PostQueuedCompletionStatus(ComplPort, dwByteTrans, 0, 0);
closesocket(s);
}
完毕port模型的更多相关文章
- Socket编程模型之完毕port模型
转载请注明来源:viewmode=contents">http://blog.csdn.net/caoshiying?viewmode=contents 一.回想重叠IO模型 用完毕例 ...
- 完毕port(CompletionPort)具体解释 - 手把手教你玩转网络编程系列之三
手把手叫你玩转网络编程系列之三 完毕port(Completion Port)具体解释 ...
- 服务器开发基础-Tcp/Ip网络模型—完成端口(Completion Port)模型
本文对于初学网络编程的极为友好,文中所有代码全部基于C语言实现,文中见解仅限于作者对于完成端口的初步认识,由于作者才疏学浅,出现的错误和纰漏,麻烦您一定要指出来,咱们共同进步.谢谢!!! 完成端口(c ...
- tflearn 在每一个epoch完毕保存模型
关键代码:tflearn.DNN(net, checkpoint_path='model_resnet_cifar10', max_checkpoints=10, tensorboard_verbos ...
- IOCP模型总结(总结回想)
IOCP旧代码重提.近期一直在玩其它方面的东东.时不时回想一下,收益多多. IOCP(I/O Completion Port,I/O完毕port)是性能最好的一种I/O模型.它是应用程序使用线程池处理 ...
- socket 由浅入深系列------ 原理(一)
来自:网络整理 个人觉得写一个网络应用程序没有是一件非常easy的事.其实,我们刚開始的时候总觉得的原则: 建立------>连接套接字------->接受一个连接---->发送数据 ...
- Cloud Foundry中DEA与warden通信完毕应用port监听
在Cloud Foundry v2版本号中,DEA为一个用户应用执行的控制模块,而应用的真正执行都是依附于warden. 更详细的来说,是DEA接收到Cloud Controller的请求:DEA发送 ...
- Linux下套接字具体解释(三)----几种套接字I/O模型
參考: 网络编程–IO模型演示样例 几种server端IO模型的简介及实现 背景知识 堵塞和非堵塞 对于一个套接字的 I/O通信,它会涉及到两个系统对象.一个是调用这个IO的进程或者线程,还有一个就是 ...
- WinSock IOCP 模型总结(附一个带缓存池的IOCP类)
前言 本文配套代码:https://github.com/TTGuoying/IOCPServer 由于篇幅原因,本文假设你已经熟悉了利用Socket进行TCP/IP编程的基本原理,并且也熟练的掌握了 ...
随机推荐
- spring 监听器 IntrospectorCleanupListener简介
转自:https://blog.csdn.net/ywb201314/article/details/51144256 其中JavaBeans Introspector是一个类,位置在Java.bea ...
- ”W: GPG 错误:http://ppa.launchpad.net lucid Release: 由于没有公钥,无法验证下列签名:“的问题
在安装更新时,即在运行,命令行sudo apt-get update 或者运行更新管理器的时候,出现如下错误: W: GPG 错误:http://ppa.launchpad.net lucid Rel ...
- 昂贵的聘礼(Dijkstra)
http://poj.org/problem?id=1062 每个物品看成一个节点,酋长的允诺也看作一个物品, 如果一个物品加上金币可以交换另一个物品,则这两个节点之间有边,权值为金币数,求第一个节点 ...
- Mysql 时间、字符串、时间戳互转
时间转字符串 select date_format(now(),'%Y-%m-%d'); 时间转时间戳 select UNIX_TIMESTAMP(now()); 时间戳转时间 ) :: 时间戳转字符 ...
- Java算法——求出两个字符串的最长公共字符串
问题:有两个字符串str1和str2,求出两个字符串中最长公共字符串. 例如:“acbbsdef”和"abbsced"的最长公共字符串是“bbs” 算法思路: 1.把两个字符串分别 ...
- html与css命名规范小结
一.命名规则说明 所有的命名最好都用小写 使用英文命名 给每一个表格和表单加上一个唯一的.结构标记id 给每个图片加上alt标签,优点在于图片发生错误时,alt可以体现给用户 二.相对网页外层重要部分 ...
- (转) 前端模块化:CommonJS,AMD,CMD,ES6
模块化的开发方式可以提高代码复用率,方便进行代码的管理.通常一个文件就是一个模块,有自己的作用域,只向外暴露特定的变量和函数.目前流行的js模块化规范有CommonJS.AMD.CMD以及ES6的模块 ...
- Unity引擎GUI之Canvas和EventSystem
最近想写一套关于UGUI所有控件的基础使用教程系列,主要是根据本人的使用心得以及部分测试附带字面翻译来写的,所以其中可能难以避免会有不正确的地方. 好了进入主题,既然是第一篇,我觉得我有必要先介绍一下 ...
- JAVA语言编程格式高级规范
作为一位开发人员,都要有严格的代码规范.为此我总结了一些代码规范案例. 目 录 1. 前言 2. 试用范围 3. JAVA命名规范-- 3.1 公共约定 3.2 Java文件.包 3.3 类.接口 ...
- 两款工作流JBPM和CCBPM的对比
以国外流行的工作流jbpm4的模式与当今中国开源的ccbpm(ccflow和jflow的总称)流程引擎对照.以便让各位能够了解到中国国情的工作流引擎与国际流行的设计规则的差别.不同.与优缺点. 国外工 ...