服务器经典稳定版iocp,个人IOCP服务器例子解说
这里写两方面的解说,一方面,解说iocp内部处理情况(这部分以个人查考写的iocp服务器和客户端写的);一方面,参考libeventlibevent-1.4.4-iocp-3 大致调整给出一个比较标准的服务器和客户端例子。新手可以通过前部分获得建立iocp的基本理解;通过后部分建立自己(基于libevent)标准的iocp代码。
一、//先来建立自己的icop吧
1)自己的iocp服务器(MyIOCPServer.cpp)
#include "stdafx.h"
#include #pragma comment(lib, "ws2_32.lib")
#include using namespace std;
// 单句柄数据
typedef struct tagPER_HANDLE_DATA
{
SOCKET Socket;
SOCKADDR_STORAGE ClientAddr;
// 将和这个句柄关联的其他有用信息,尽管放在这里面吧
}PER_HANDLE_DATA, *LPPER_HANDLE_DATA;
// 但I/O 操作数据
typedef struct tagPER_IO_DATA
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
char buffer[1024];
int BufferLen;
int OperationType; // 可以作为读写的标志,为简单,我忽略了
}PER_IO_DATA, *LPPER_IO_DATA;
//线程函数
DWORD WINAPI ServerWorkerThread(LPVOID lpParam);
DWORD WINAPI ServerWorkerThread(LPVOID lpParam)
{
HANDLE CompletionPort = (HANDLE)lpParam;
DWORD BytesTransferred;
LPOVERLAPPED lpOverlapped;
LPPER_HANDLE_DATA PerHandleData = NULL;
LPPER_IO_DATA PerIoData = NULL;
DWORD SendBytes;
DWORD RecvBytes;
DWORD Flags;
BOOL bRet = FALSE;
while (TRUE) //无限循环
{
bRet = GetQueuedCompletionStatus(CompletionPort,&BytesTransferred,(PULONG_PTR)&PerHandleData,(LPOVERLAPPED*)&lpOverlapped,INFINITE);
// 检查成功的返回,这儿要注意使用这个宏CONTAINING_RECORD
PerIoData = (LPPER_IO_DATA)CONTAINING_RECORD(lpOverlapped,PER_IO_DATA,Overlapped);
// 先检查一下,看看是否在套接字上已有错误发生
if (0 == BytesTransferred)
{
closesocket(PerHandleData->Socket);
GlobalFree(PerHandleData);
GlobalFree(PerIoData);
continue;
}
// 数据处理
char sendBuf[100];
sprintf(sendBuf,"Welcome %s to %d %d \n",PerIoData->DataBuf.buf,PerHandleData->Socket,::GetCurrentThreadId());
send(PerHandleData->Socket,sendBuf,strlen(sendBuf)+1,0);
//WSASend()
/*DataBuf.len = DATA_BUFSIZE;
DataBuf.buf = buffer;
for(i=0; i < SEND_COUNT ;i++) {
WSASend(PerHandleData->Socket, &DataBuf, 1, &SendBytes, 0, &SendOverlapped, NULL); */
// 成功了!!!这儿就收到了来自客户端的数据
cout << PerIoData->DataBuf.buf << ::GetCurrentThreadId() << endl;
Flags = 0;
// 为下一个重叠调用建立单I/O 操作数据
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->DataBuf.len = 1024;
PerIoData->DataBuf.buf = PerIoData->buffer;
PerIoData->OperationType = 0; // read
WSARecv(PerHandleData->Socket,&(PerIoData->DataBuf),1,&RecvBytes,&Flags,&(PerIoData->Overlapped),NULL);
}
return 0;
}
int main(int argc, _TCHAR* argv[])
{
//头部申明
HANDLE CompletionPort;
WSADATA wsd;
SYSTEM_INFO SystemInfo;
SOCKADDR_IN InternetAddr;
SOCKET Listen;
// 加载WinSock2.2
WSAStartup(MAKEWORD(2, 2), &wsd);
// 1.创建一个I/O 完成端口
CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
// 2.确定系统中有多少个处理器
GetSystemInfo(&SystemInfo);
// 3.基于系统中可用的处理器数量创建工作器线程
for (int i = 0; i < int(SystemInfo.dwNumberOfProcessors * 2); ++i)
{
HANDLE ThreadHandle;
// 创建一个服务器的工作器线程,并将完成端口传递到该线程
ThreadHandle = CreateThread(NULL,0,ServerWorkerThread,CompletionPort,0,NULL);
CloseHandle(ThreadHandle);
}
// 4.创建一个监听套接字,以下的套路都是固定的。
Listen = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
//绑定和监听
InternetAddr.sin_family = PF_INET;
InternetAddr.sin_port = htons(6000);
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(Listen, (SOCKADDR*)&InternetAddr, sizeof(InternetAddr));
listen(Listen, 5);
//无限循环
BOOL b = TRUE;
while (b)
{
PER_HANDLE_DATA * PerHandleData = NULL;
SOCKADDR_IN saRemote;
SOCKET Accept;
int RemoteLen;
// 5.接收连接,并分配完成端口,这儿可以用AcceptEx 来代替,以创
// 建可伸缩的Winsock 应用程序。
RemoteLen = sizeof(saRemote);
Accept = accept(Listen, (SOCKADDR*)&saRemote, &RemoteLen);
// 6.创建用来和套接字关联的单句柄数据信息结构
PerHandleData = (LPPER_HANDLE_DATA)GlobalAlloc(GPTR,sizeof(PER_HANDLE_DATA));
//cout << "Socket number " << Accept << " connected" << endl;
PerHandleData->Socket = Accept;
memcpy(&PerHandleData->ClientAddr, &saRemote, RemoteLen);
// 7.将接受套接字和完成端口关联起来
CreateIoCompletionPort((HANDLE)Accept,CompletionPort,(DWORD)PerHandleData,0);
// 开始在接受套接字上处理I/O
// 使用重叠I/O 机制,在新建的套接字上投递一个或多个异步
// WSARecv 或 WSASend 请求。这些I/O 请求完成后,工作者线程
// 会为I/O 请求提供服务,之后就可以坐享其成了
static int const DATA_BUFSIZE = 4096;
DWORD RecvBytes = 0;
DWORD Flags = 0;
// 单I/O 操作数据
LPPER_IO_DATA PerIoData = NULL;
PerIoData = (LPPER_IO_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_DATA));
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->DataBuf.len = 1024;
PerIoData->DataBuf.buf = PerIoData->buffer;
PerIoData->OperationType = 0; // read
WSARecv(PerHandleData->Socket,&(PerIoData->DataBuf),1,&RecvBytes,&Flags,&(PerIoData->Overlapped),NULL);
}
return 0;
}
2)自己的iocp客户端(MyIOCPClient.cpp)
#include "stdafx.h"
#include #pragma comment(lib, "ws2_32.lib")
#include
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
while (true)
{
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
send(sockClient,"This is lisi",strlen("This is lisi")+1,0);
char recvBuf[100];
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
closesocket(sockClient);
}
WSACleanup();
}
服务器经典稳定版iocp,个人IOCP服务器例子解说相关推荐
- kinhdown稳定版无法连接服务器,KinhDown稳定版
KinhDown稳定版是一款非常稳定的百度云pc下载器,在KinhDown稳定版中有着极为强大的工嗯呢该,能够为的敬爱啊使用最快的速度完成对资源的下载,比原版的客户端不知道强了多少倍,带你一起告别蜗牛 ...
- win7系统搭建tftp服务器,Win7旗舰版如何开启TFTP服务器|开启Win7旗舰版TFTP服务器的方法...
在Win7旗舰版上,我们开启TFTP服务器呢?这个TFTP服务器是一种简单文件传输协议,在我们的WIn7旗舰版跟服务器交换数据时,就需要到TFTP服务器,但是有些Win7旗舰版是没有开启TFTP服务器 ...
- 桌面版阴阳师无法连接服务器,阴阳师桌面版连接不上服务器怎么解决[多图]
阴阳师桌面版上线了,但是有很多小伙伴反映桌面版连接不上服务器,那该如何是好呢?本期手游汇小编带来阴阳师桌面版连接不上服务器解决思路,希望对你有所帮助! 阴阳师桌面版连接不上服务器解决思路 阴阳师桌面版 ...
- LOL国服哪个服务器最稳定,《LOL》国服服务器排名怎么样 国服服务器排名一览...
导 读 <LOL>国服服务器排名介绍.国服有着众多的服务器,但是很多小伙伴不知道该怎么选服务器,哪个服务器比较厉害,挑战性更强呢?下面一起来看看官方的服务器排名吧,看看哪个服务器最适合你! ...
- 方配网站服务器64位版,方配网站服务器(FPWebServer) v3.0 支持64位
FPWebServer又称方配网站服务器,这是一款强大的服务器环境组件全自动安装工具,可以一键搭配asp..net.php.jsp等环境,并拥有图形化的管理界面.无连接限制.多种环境同时运行.多站点同 ...
- 魔兽世界新开服务器那个稳定,国服新开登陆服务器需要做好的准备
今日网易最新公告: 我们在此提醒,<魔兽世界>内测将于明天7月30日开始.为准备此次内测,若您尚未绑定账号和更新客户端,请将您此前的<魔兽世界>账号绑定到新创建的战网通行证,并 ...
- 英雄联盟哪个服务器最稳定,LOL新人进哪个服务器比较好?当然最后一个啦!个个人善嘴又甜...
这里是胡说游戏! 无论你有什么想看的.想听的.想知道的,告诉我,满足你! 点关注,不迷路! 英雄联盟这个游戏还有新玩家?不会吧? 英雄联盟这个游戏发行于2011年,至今已经是九年了.作为一个九年的老游 ...
- c++服务器开发学习--02--MySQL,Redis,ASIO,iocp,TrinityCore代码结构,c++对象模型
c++服务器开发学习--02--MySQL,Redis,ASIO,iocp,TrinityCore代码结构,c++对象模型 MySQL 问题 Redis Asio iocp TrinityCore代码 ...
- 腾讯云推出首款自研服务器星星海;苹果新款Mac Pro整套配齐超30万;Fedora 31稳定版发布|极客头条...
快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「CSDN 极客头条」,是从 CSDN 网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道.风里雨里,我们将每天为朋友们,播报最新鲜有 ...
最新文章
- Android性能调优篇之探索垃圾回收机制
- 关于微信聊天记录双击弹出具体显示内容的效果
- android 前摄屏幕补光,异形显示屏及其前置摄像头的拍照补光方法与流程
- Winform中设置ZedGraph的曲线为折线、点折线、散点图
- 快乐学算法之:字典树Trie
- 简练软考知识点整理-控制范围
- 异常堆栈信息丢失?到底是怎么回事?
- delphi tpanel 内凹效果_别墅装修公司前十名|别墅装修效果图|现代精致简约
- 区块链,到底是美好未来还是题材炒作?
- 计算机多余自动启动项,去掉多余的开机启动项
- ACDsee的安装过程
- 显示器接口_显示器接口 - CNZHIQIANG
- Android dev 设备访问权限 777,Android Studio:/ dev / kvm设备权限被拒绝
- 树莓派小车————全部代码
- html句号图标,html标点符号相关符号
- 未来教育安装后打不开
- Apsara Clouder云计算专项技能认证考试题目和答案
- C语言遍历目录文件并排序
- SPI 接口OLED 模块 - 兼容5V 和3.3V 电平
- Android安全专项-Apk加固