iocp详解_iocp是异步io吗

iocp详解_iocp是异步io吗#include”SOCKET.h”#includeDWORDWINAPIThreadProc(LPVOIDpvParam);#definePORT8080#defineLISTEN_QUEUE200//AcceptEx和GetAcceptExSockaddrs的函数指针,用于调用这两个扩展函数LPFN_ACCEPTEX       

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用
#include “SOCKET.h”

#include <Windows.h>

DWORD WINAPI ThreadProc(LPVOID pvParam);

#define PORT
8080

#define LISTEN_QUEUE
200

// AcceptEx 和 GetAcceptExSockaddrs 的函数指针,用于调用这两个扩展函数

LPFN_ACCEPTEX                lpfnAcceptEx;                

LPFN_GETACCEPTEXSOCKADDRS
lpfnGetAcceptExSockAddrs; 

void PostAcceptEx(IOCPHandle_s & listenHandle)

{


IO_DATA_s * p_io_data = new IO_DATA_s;


p_io_data->socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);


listenHandle.Push(p_io_data);


p_io_data->type = ACCEPT;


lpfnAcceptEx(listenHandle.socket, p_io_data->socket, &p_io_data->addr, 0, 0, sizeof(SOCKADDR_IN) + 16, &p_io_data->len, &p_io_data->ol);

}

int main()

{


SocketInit();


IOCPHandle_s
listenHandle;


listenHandle.socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);


listenHandle.addr.sin_family = AF_INET;


listenHandle.addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);


listenHandle.addr.sin_port = htons(PORT);


HANDLE
IOCPhandle;


IOCPhandle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0 );


::CreateThread(0, 0, ThreadProc, (void *)IOCPhandle, 0, 0);


::bind(listenHandle.socket, (SOCKADDR *)&listenHandle.addr, sizeof(SOCKADDR));


::listen(listenHandle.socket, LISTEN_QUEUE);


CreateIoCompletionPort((HANDLE)listenHandle.socket, IOCPhandle, (unsigned long)&listenHandle, 0);


// 使用AcceptEx函数,因为这个是属于WinSock2规范之外的微软另外提供的扩展函数


// 所以需要额外获取一下函数的指针,


// 获取AcceptEx函数指针


GUID GuidAcceptEx = WSAID_ACCEPTEX;  


GUID GuidGetAcceptExSockAddrs = WSAID_GETACCEPTEXSOCKADDRS; 


DWORD dwBytes = 0;  


WSAIoctl(


listenHandle.socket, 


SIO_GET_EXTENSION_FUNCTION_POINTER, 


&GuidAcceptEx, 


sizeof(GuidAcceptEx), 


&lpfnAcceptEx, 


sizeof(lpfnAcceptEx), 


&dwBytes, 


NULL, 


NULL);


// 获取GetAcceptExSockAddrs函数指针,也是同理


WSAIoctl(


listenHandle.socket, 


SIO_GET_EXTENSION_FUNCTION_POINTER, 


&GuidGetAcceptExSockAddrs,


sizeof(GuidGetAcceptExSockAddrs), 


&lpfnGetAcceptExSockAddrs, 


sizeof(lpfnGetAcceptExSockAddrs),   


&dwBytes, 


NULL, 


NULL);


for(i32 i = 0 ; i < 50 ; ++i)


PostAcceptEx(listenHandle);


printf(“主线程阻塞\n”);


Sleep(INFINITE);


SocketUnInit();


getchar();


return 0;

}

DWORD WINAPI ThreadProc(LPVOID pvParam)

{


HANDLE
IOCPhandle = pvParam;


DWORD   dwBytesTransfered = 0;


IOCPHandle_s * p_IOCPhandle;


IO_DATA_s * p_IOdata;


BOOL bReturn;


while(true)


{



//实际操作字节数


bReturn = GetQueuedCompletionStatus(IOCPhandle,&dwBytesTransfered,(unsigned long *)&p_IOCPhandle,(OVERLAPPED **)&p_IOdata,INFINITE);


if(!bReturn)


{


printf(“出错\n”);


closesocket(p_IOCPhandle->socket);


delete p_IOCPhandle;


delete p_IOdata;


continue;


}


else if(dwBytesTransfered == 0 && (p_IOdata->type == RECV || p_IOdata->type == SEND))


{


printf(“客户端关闭了连接!\n”);


closesocket(p_IOCPhandle->socket);


delete p_IOCPhandle;


delete p_IOdata;


}


else


{


printf(“处理IO服务\n”);


switch(p_IOdata->type)


{


case RECV:


{


printf(“RECV\n”);


p_IOdata->buf.buf[dwBytesTransfered] = ‘\0’;


printf(“数据:%s 长度:%d\n”,p_IOdata->buf.buf,dwBytesTransfered);


p_IOdata->SetZero();


p_IOdata->type = RECV;


p_IOdata->buf.buf = p_IOCPhandle->recv_buff;


p_IOdata->buf.len = BUFF_SIZE;


p_IOdata->flags = 0;


int nBytesRecv = WSARecv(p_IOCPhandle->socket, &p_IOdata->buf, 1, &p_IOdata->len, &p_IOdata->flags, &p_IOdata->ol, 0);


int ret = WSAGetLastError();


if ((SOCKET_ERROR == nBytesRecv) && (WSA_IO_PENDING != ret))


{


printf(“投递RECV失败\n”);


}


}


break;


case SEND:


{





}


break;


case ACCEPT:


{


printf(“ACCEPT\n”);


IOCPHandle_s * p_accepthandle = new IOCPHandle_s;


p_accepthandle->socket = p_IOdata->socket;


//赋值SOCKET的属性与LISTENSOCKET的属性一样


setsockopt( p_accepthandle->socket,


SOL_SOCKET,


SO_UPDATE_ACCEPT_CONTEXT,


(char*)&p_IOCPhandle->socket,


sizeof(p_IOCPhandle->socket) ) ;


//lpfnGetAcceptExSockAddrs(&p_IOdata->buf.buf,0, 0, sizeof(SOCKADDR_IN) + 16, 0, 0, (LPSOCKADDR*)&p_addr, &remoteLen);


//memcpy(&p_accepthandle->addr, &p_IOdata->addr, sizeof(SOCKADDR_IN) + 16);


//printf(“IP:%s 端口:%d\n”,inet_ntoa(p_accepthandle->addr.sin_addr),ntohs(p_accepthandle->addr.sin_port));


IO_DATA_s * p_iodata = new IO_DATA_s;


p_accepthandle->Push(p_iodata);


CreateIoCompletionPort((HANDLE)p_accepthandle->socket, IOCPhandle, (unsigned long)p_accepthandle, 0);


p_iodata->type = RECV;


p_iodata->buf.buf = p_accepthandle->recv_buff;


p_iodata->buf.len = BUFF_SIZE;


p_iodata->flags = 0;


int nBytesRecv = WSARecv(p_accepthandle->socket, &p_iodata->buf, 1, &p_iodata->len, &p_iodata->flags, &p_iodata->ol, 0);


if ((SOCKET_ERROR == nBytesRecv) && (WSA_IO_PENDING != WSAGetLastError()))


{


printf(“投递RECV失败\n”);


return false;


}


p_IOdata->SetZero();


p_IOdata->socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);


p_IOdata->type = ACCEPT;


lpfnAcceptEx(p_IOCPhandle->socket, p_IOdata->socket, &p_IOdata->addr, 0, 0, sizeof(SOCKADDR_IN) + 16, &p_IOdata->len, &p_IOdata->ol);


}


break;


default:


break;


}


}


 


}


return 0;

}

/*******************************************************SOCKET.h************************************************/

#include <winsock2.h>
#include <ws2tcpip.h>
#include <fcntl.h>
#include <MSWSock.h>
#include <vector>
#include <string.h>
#pragma comment(lib ,”ws2_32″)
void SocketInit()
{

WSADATA wsaData;// 库
WSAStartup(MAKEWORD(2,2),&wsaData); //初始化
}
void SocketUnInit()
{

WSACleanup();//关闭
}
#define BUFF_SIZE 120
enum TYPE {SEND,RECV,ACCEPT,INIT};
typedef int i32;
typedef char i8;
typedef unsigned int u32;
typedef unsigned char u8;

struct IO_DATA_s
{

IO_DATA_s()
{

type = INIT;
SetZero();
}
WSAOVERLAPPED ol;
SOCKET socket; //操作的SOCKET
SOCKADDR_IN addr; //地址
DWORD len; //操作长度
DWORD flags; //标志
TYPE type; //操作类型
WSABUF buf; //WindowBUF
void SetZero()
{

memset(this, 0, sizeof(IO_DATA_s));
}
};
struct IOCPHandle_s
{

SOCKET socket; //套接字
SOCKADDR_IN addr; //地址
std::vector<IO_DATA_s *> io_array; //IO操作的地址
i8 send_buff[BUFF_SIZE]; //发送缓存
DWORD send_len;
char recv_buff[BUFF_SIZE]; //接收缓存
DWORD recv_len;
void Push(IO_DATA_s * v)
{

io_array.push_back(v);
}
};

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/187962.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • kafka性能测试、性能分析与性能调优[通俗易懂]

    kafka性能测试、性能分析与性能调优[通俗易懂]前言:最近在做kafka、mq、redis、fink、kudu等在中间件性能压测,压测kafka的时候参考了这篇文章,大家可以借鉴下!一、测试环境测试使用到三台机器,机器配置如下:共同配置:Intel®Core™i7-7700CPU@3.60GHz、Cores:4、Threads:232GB内存1000Mb/sec网卡差异化配置2TB、7200rpm、SATA3.1,6.0Gb/s(current:6.0Gb/s)1TB、7200rpm、SATA3.1,6.0Gb

    2022年5月27日
    44
  • 联盟卡结合异业联盟,如何建立一个完善的联盟生态会员体系?「建议收藏」

    联盟卡结合异业联盟,如何建立一个完善的联盟生态会员体系?「建议收藏」对于我们所认知的联盟,生态就是联盟生态,也就是说,如果我们要做一个联盟卡,然后通过我们的联盟卡去建立我们的会员。那如何来建立呢?分四个方式来讲。首先第一个方式要建立完善的一个会员体系,把这个会员体系给架构起来。如何成为我们平台的会员,以及说成有平台会员之后可以享受平台的一种权益。再者的话就是如何让我们的会员去帮助我们平台去做裂变,也就是我们经常讨论的一个问题,如何去做分享?那么在这个环节中如何去做一个线上电子权益卡,通过入口让用户可以去购买,或者叫免费卡也行,这个都是由平台去做设定的,开通后可以去享受我们相

    2022年6月15日
    28
  • imx6 添加matrix keypad

    imx6 添加matrix keypadfreescale增加matrixkeypad1.添加设备树,imx6有矩阵键盘功能,支持8*8的键盘kernel_imx/arch/arm/boot/dts/imx6qdl.dtsi/*addedbyyue.zhong*/#include//键值定义的地方,这是一个链接文件,指向kernel_imx/include/dt-bindings/input/i

    2022年6月14日
    75
  • leetcode-19删除链表的倒数第 N 个结点

    leetcode-19删除链表的倒数第 N 个结点原题链接给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。进阶:你能尝试使用一趟扫描实现吗?示例 1:输入:head = [1,2,3,4,5], n = 2输出:[1,2,3,5]示例 2:输入:head = [1], n = 1输出:[]示例 3:输入:head = [1,2], n = 1输出:[1]提示:链表中结点的数目为 sz1 <= sz <= 300 <= Node.val <= 1001 <= n <= s

    2022年8月9日
    5
  • ora-01006:绑定变量不存在_输出参数不是绑定变量

    ora-01006:绑定变量不存在_输出参数不是绑定变量  #命令行新建job错误:ORA-01008并非所有变量都已绑定。 1、改正前代码:DECLAREjobNUMBER;begin      sys.dbms_job.submit(job=&gt;:job, what=&gt;’P_AUTO_FETCH_RECORDS;’, next_date=&gt;to_…

    2025年9月25日
    6
  • 什么是宿主机?_esxi宿主机

    什么是宿主机?_esxi宿主机就是主机,这个概念是相对于子机而言的,比如你安装有虚拟机的话,那么相对于虚拟机而言,你正在使用的计算机就是宿主机,虚拟机是安装在主机上的,必须在主机上才能运行,主机就是一个“宿主”。…

    2022年4月19日
    207

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号