当前位置: 首页 > news >正文

二级黄冈站在线注册网站

二级黄冈站,在线注册网站,西安大雁塔图片,哪些网站做商标注册1.什么是IOCP IOCP(Input Output Completion Port)输入输出完成端口。其实就是基于重叠I/O的一种改进的模型。 重叠I/O具有缺点:重复调用非阻塞模式的accpet函数和以进入alertablewait状态为目的的SleepEx函数会影响程序性能。 而IOCP提供…

1.什么是IOCP

IOCP(Input Output Completion Port)输入输出完成端口。其实就是基于重叠I/O的一种改进的模型。

重叠I/O具有缺点:重复调用非阻塞模式的accpet函数和以进入alertablewait状态为目的的SleepEx函数会影响程序性能

而IOCP提供的解决方案便是:让主线程调用accept函数,单独创建至少一个线程来负责所有I/O的前后处理

但请不要过分关注在线程上,主要还是如下问题:

        1.I/O是否以非阻塞模式工作?

        2.如何确定非阻塞模式的I/O是否完成?

2.分阶段实现IOCP程序

2.1 实现原理

IOCP会将已完成的I/O信息注册到CP对象(Completion Port完成端口),而我们就可以通过CP对象来获取I/O是否完成的信息,所以有下面两项工作:

  • 创建完成端口对象
  • 建立完成端口对象和套接字之间的联系 

此时的套接字必须赋予重叠属性。

2.2 创建CP对象

#include<windows.h>HANDLE CreateIoCompletionPort(
HANDLE fileHandle,                //创建CP对象时传递INVALID_HANDLE_VALUE
HANDLE ExistingCompletionPort,    //创建CP对象时传递NULL
ULONG_PTR CompletionKey,          //创建CP对象时传递0
DWORD NumberOfConcurrentThreads   //分配给CP对象的用于处理I/O的线程数。//例如:该参数为2时,说明分配给CP对象的可以同时运行的线程数最多为2个//如果为0时,那么系统中CPU的个数就是可同时运行的最大线程数
);
成功返回CP对象句柄
失败返回NULL

2.3 创建和套接字连接完成的端口对象

#include<windows.h>HANDLE CreateIoCompletionPort(
HANDLE FileHandle,                //要连接到CP对象的套接字句柄
HANDLE ExistingCompletionPort,    //要连接套接字的CP对象句柄
ULONG_PTR CompletionKey,          //传递已完成I/O相关信息
DWORD NumberOfConcurrentThreads   //无论传递何值,只要第二个参数非NULL就会被忽略
);
成功返回CP对象句柄
失败返回NULL

函数功能:将FileHandle句柄指向的套接字和ExistingCompletionPort指向的CP对象相连。

调用此函数后:只要针对FileHandle的I/O完成,相关信息就会注册到ExistingCompletionPort里。

注意:第三个参数“传递已完成I/O相关信息”的意思是,你可以像重叠I/O里使用Complition routine来确认I/O方式里把相关信息填写到hEvent里的那样,写入其他信息,这样当I/O完成就可以获取了。

2.4 确认完成端口已完成的I/O和线程I/O处理

#include<windows.h>BOOL GetQueuedCompletionStatus(
HANDLE CompletionPort,        //注册有已完成I/O信息的CP对象句柄
LPDWORD lpNumberOfBytes,      //保存I/O过程中传输的数据大小的变量地址值
PULONG_PTR lpCompletionKey,   //保存CreateIoCompleytionPort函数第三个参数值得变量地址值
LPOVERLAPPED* lpOverlapped,   //保存调用WSASend、WSARecv函数时传递的OVERLAPPED结构体地址的变量地址值
DWORD dwMilliseconds          //超时信息,超过该指定时间后将返回FALSE并跳出函数。//传递INFINITE时,程序将阻塞,直到已完成I/O信息写入CP对象
);
成功返回TRUE
失败返回FALSE

注意:

  • 调用此函数的线程数量不能超过CreateIoCompletionPort时指定的线程数。
  • 此函数并不知道当前是输入信息状态还是输出信息状态,需要自行判断。

3. 实现IOCP模型的回声服务器端

思路:每连接一个客户端就创建一个线程,然后主线程里先接收一次数据,在子线程里通过GetQueuedCompletionStatus函数阻塞住线程,判断I/O状态,接着把接收的数据发送给客户端,再次进入接收状态,如此循环通信。

变量:

struct ClientInfo结构体:存有套接字和套接字地址族信息,在CreateIoCompletionPort函数里,建立套接字和CP的连接的时候,当做第三参数传入

struct CPInfo结构体:存有一个OVERLAPPED、WSABUF信息,以及还有一个int型用来判断当前是RECV还是SEND,在执行WSARecv函数时当做第六个参数进行传入。运用下面的知识点,所以可以在子线程执行GetQueuedCompletionStatus函数时,取得的第一个成员的地址,也就是这整个结构体的地址。

知识点:结构体变量地址值与结构体第一个成员的地址值相同。

struct CPInfo
{OVERLAPPED overlapped;WSABUF wsabuf;int mode;			//0:RECV 1:SEND
};
CPInfo data;
if(&data==&data.overlapped)
{std::cout<<"TRUE"<<std::endl;
}
else
{std::cout<<"FALSE"<<std::endl;
}
输出TRUE
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<iostream>
#include<WinSock2.h>
#include<process.h>
#include<Windows.h>
#include<malloc.h>
#include<string>struct ClientInfo
{SOCKET socket;sockaddr_in socketAddr;
};struct CPInfo
{OVERLAPPED overlapped;WSABUF wsabuf;int mode;			//0:RECV 1:SEND
};unsigned WINAPI threadClient(void* arg);int main()
{WSADATA wsaData;if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)){std::cout << "start up fail!" << std::endl;return 0;}SOCKET server = WSASocket(PF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);if (server == INVALID_SOCKET){std::cout << "socket fail!" << std::endl;return 0;}int mode = 1;ioctlsocket(server, FIONBIO, (u_long*)&mode);sockaddr_in serverAddr;memset(&serverAddr, 0, sizeof(serverAddr));serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);serverAddr.sin_port = htons(9130);if (SOCKET_ERROR == bind(server, (sockaddr*)&serverAddr, sizeof(serverAddr))){std::cout << "bind fail!" << std::endl;return 0;}if (SOCKET_ERROR == listen(server, 2)){std::cout << "listen fail!" << std::endl;return 0;}while (true){sockaddr_in clientAddr;memset(&clientAddr, 0, sizeof(clientAddr));int clientAddrLen = sizeof(clientAddr);SOCKET client = accept(server, (sockaddr*)&clientAddr, &clientAddrLen);if (client == SOCKET_ERROR){if (WSAGetLastError() == WSAEWOULDBLOCK)	//说明此时没有客户端连接{continue;}std::cout << "accept fail!" << std::endl;}else{HANDLE cpObject = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);if (cpObject == NULL){std::cout << "Create CP fail!" << std::endl;continue;}ClientInfo* clientinfo = new ClientInfo();clientinfo->socket = client;clientinfo->socketAddr = clientAddr;CreateIoCompletionPort((HANDLE)client, cpObject, (ULONG_PTR)clientinfo, 0);unsigned threadId;if (0 == _beginthreadex(NULL, 0, threadClient, (void*)&cpObject, 0, &threadId))	//创建一个线程{std::cout << "thread create fail!" << std::endl;continue;}CPInfo* cpinfo = new CPInfo();cpinfo->mode = 0;memset(&cpinfo->overlapped, 0, sizeof(cpinfo->overlapped));char buff[1024];cpinfo->wsabuf.buf = buff;cpinfo->wsabuf.len = sizeof(buff);DWORD readLen;DWORD flag = 0;WSARecv(client, &cpinfo->wsabuf, 1, &readLen, &flag, &cpinfo->overlapped, NULL);}}closesocket(server);WSACleanup();
}unsigned WINAPI threadClient(void* arg)
{HANDLE cpObject = *(HANDLE*)arg;CPInfo* cpinfo;ClientInfo* clientinfo;while (true){DWORD readLen;GetQueuedCompletionStatus(cpObject, &readLen, (PULONG_PTR)&clientinfo, (LPOVERLAPPED*)&cpinfo, INFINITE);if (readLen == 0){std::cout << "客户端:" << inet_ntoa(clientinfo->socketAddr.sin_addr) << "断开连接!" << std::endl;break;}if (cpinfo->mode == 0)		//recv{std::cout << "客户端发来的消息:" << cpinfo->wsabuf.buf << std::endl;DWORD flag = 0;cpinfo->mode = 1;WSASend(clientinfo->socket, &cpinfo->wsabuf, 1, &readLen, flag, &cpinfo->overlapped, NULL);CPInfo* cpinfo2 = new CPInfo();cpinfo2->mode = 0;memset(&cpinfo2->overlapped, 0, sizeof(cpinfo2->overlapped));char buff[1024];cpinfo2->wsabuf.buf = buff;cpinfo2->wsabuf.len = sizeof(buff);DWORD readLen2;WSARecv(clientinfo->socket, &cpinfo2->wsabuf, 1, &readLen2, &flag, &cpinfo2->overlapped, NULL);}else						//send{delete cpinfo;}}CloseHandle(cpObject);closesocket(clientinfo->socket);return 0;
}
http://www.hengruixuexiao.com/news/25749.html

相关文章:

  • 青岛永诚网络科技有限公司重庆seo教程搜索引擎优化
  • 首页凡客搜索引擎优化教材答案
  • 哈尔滨网络招聘seo 网站优化推广排名教程
  • 新网站如何做流量百度优化公司
  • 专业做网站团队重庆seo标准
  • 企业网站底部如何推广一个新的app
  • 郑州区块链数字钱包网站开发公司成品app直播源码有什么用
  • 网站搜索引擎优化推广疫情防控最新数据
  • 郑州网站推广公司地址西安百度爱采购推广
  • 电脑怎样做幻灯片的网站阜阳seo
  • 台州网站制作建设免费设计模板网站
  • 用dw做电子商务网站步骤太原今日新闻最新头条
  • 做移动网站优化排百度关键词规划师
  • 南京关键词网站排名广州疫情最新动态
  • 无限建站系统百度快速收录账号购买
  • 茂名企业做网站免费好用的网站
  • ai智能生成图片免费网站北京seo代理商
  • 蕲春县住房和城乡建设局网站steam交易链接怎么改
  • 怎做直销网站爱站长尾词
  • 网站二级目录做优化东莞seo收费
  • 做写真网站犯法吗线上推广的优势和好处
  • 南宁网站推广策略it培训机构
  • 中国建设网查询平台网址高州网站seo
  • 专门做母婴的网站网络推广经验
  • 有没有做试卷的网站怎样优化网站排名
  • 解除网站开发合同 首付款是否退自助建站系统平台
  • 你会怎么做外国的网站常用于网站推广的营销手段是
  • 嘉兴推广网站中国新冠一共死去的人数
  • 国家税务总局网址入口官网百度seo关键词报价
  • 做网站在自己电脑建立虚拟机免费二级域名分发