这里写两方面的解说,一方面,解说iocp内部处理情况(这部分以个人查考写的iocp服务器和客户端写的);一方面,参考libeventlibevent-1.4.4-iocp-3 大致调整给出一个比较标准的服务器和客户端例子。新手可以通过前部分获得建立iocp的基本理解;通过后部分建立自己(基于libevent)标准的iocp代码。

一、//先来建立自己的icop吧

1)自己的iocp服务器(MyIOCPServer.cpp)

#include "stdafx.h"
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#include <iostream>
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 <Winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#include <stdio.h>

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服务器例子解说相关推荐

  1. 服务器经典稳定版iocp,个人IOCP服务器例子解说

    这里写两方面的解说,一方面,解说iocp内部处理情况(这部分以个人查考写的iocp服务器和客户端写的):一方面,参考libeventlibevent-1.4.4-iocp-3 大致调整给出一个比较标准 ...

  2. PHP服务器脚本实例,Shell脚本实现的一个简易Web服务器例子分享_linux shell

    这篇文章主要介绍了Shell脚本实现的一个简易Web服务器例子分享,本文实现的Web服务器非常简单实用,可以在你不想安装nginx.apache等大型WEB服务器时使用,需要的朋友可以参考下 假设你想 ...

  3. 【学习Koa】原生koa2 静态资源服务器例子

    实现思路 首先读取当前路径下所有的文件和文件夹 当去点击某个列表项时判断其实文件还是文件夹,文件的话直接读取,文件夹则再次利用上一个步骤读取并展示 文件结构 代码 index.js 入口文件 cons ...

  4. 轻松创建nodejs服务器(1):一个简单nodejs服务器例子

    这篇文章主要介绍了一个简单nodejs服务器例子,本文实现了一个简单的hello world例子,并展示如何运行这个服务器,需要的朋友可以参考下 我们先来实现一个简单的例子,hello world. ...

  5. Nodejs实现的一个静态服务器例子

    参考cnodejs.org上面的静态服务器例子,写了下面的一个nodejs静态服务器例子,里面包含cache,压缩,贴代码如下 /** * 静态文件服务器测试例子 * User: xuwm * Dat ...

  6. linux mysql多实例启动_Mysql实例Linux下启动多个mysql服务器例子

    <Mysql实例Linux下启动多个mysql服务器例子>要点: 本文介绍了Mysql实例Linux下启动多个mysql服务器例子,希望对您有用.如果有疑问,可以联系我们. MYSQL教程 ...

  7. python iocp_[网络开发]IOCP完整例子

    本文是我在学习IOCP的时候,第一次写一个完整的例子出来,当然了,参考了CSDN上一些朋友的博客,大部分都是按照他们的思路写的,毕竟我是初学者,参考现成的学起来比较快.当然了,真正用到项目中的IOCP ...

  8. phpsocket客户端以及服务器例子

    一个菜鸟朋友,突然问了我这个问题...现在稍稍有点时间,就写了一个简单的例子给他,顺便贴上来 服务器端: <?php /*** @author 邹颢 zouhao619@gmail.com*/ ...

  9. Node.js 极简入门Helloworld版服务器例子

    粗浅得很,纯属备忘. // 内置http模块,提供了http服务器和客户端功能(path模块也是内置模块,而mime是附加模块) var http=require("http"); ...

最新文章

  1. instagram api java_如何在没有用户交互的情况下获得instagram access_token(新api)?...
  2. 无刷新删除 Ajax,JQuery
  3. html向左箭头样式,详解Bootstrap的纯CSS3箭头按钮样式
  4. Android Studio 插件开发详解一:入门练手
  5. 给JavaScript的单个对象定义属性和属性的元数据
  6. 【以太坊源码】mpt实现
  7. 通过shell脚本防止端口扫描
  8. 设计某高校学生选课管理系统
  9. 2019FME博客大赛——FME在室内地图数据构建中的应用
  10. 项目管理工具一:职责清晰的6W1H原则
  11. Java线程之线程的五种状态
  12. Super odometry:以IMU为核心的激光雷达视觉惯性融合框架(ICRA2021)
  13. C28x FIR - Filter 示例汇编代码解读
  14. mysql联合索引原理
  15. 华为公司面试新员工的有关计算机网络的题目和答案
  16. 爬虫基础之HTTP基本原理
  17. excel插入散点图按时刻设置横坐标刻度值
  18. 【总结】GitHub的使用
  19. 两组回归系数差异检验_如何检验两个回归系数的差异性?我做调节分析。
  20. 连接wifi推送广告

热门文章

  1. AdminLTE基本使用介绍
  2. vue介绍及环境安装
  3. Spring ribbon
  4. bt5重启网卡命令_BackTrack 5 简单网络配置命令
  5. 常见MOS管型号及参数对照表
  6. 2.3微秒的特征点匹配
  7. jQuery Mobile和UI合并组新项目,这波能赢么?
  8. IE下iframe跨域session和cookie失效问题的解决方案
  9. Python 进程与线程小随笔
  10. 关于迭代測试的一些思考