一、重叠I/O回声服务器端

服务端:

 #include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h> #define BUF_SIZE 1024
void ErrorHandling(char *message);
void CALLBACK ReadCompRoutine(DWORD, DWORD, LPWSAOVERLAPPED, DWORD);
void CALLBACK WriteCompRoutine(DWORD, DWORD, LPWSAOVERLAPPED, DWORD); typedef struct
{
SOCKET hClntSock;
char buf[BUF_SIZE];
WSABUF wsaBuf;
}PER_IO_DATA, *LPPER_IO_DATA; int main(int argc, char *argv[])
{
if (argc != ) {
printf("Usage : %s <port>\n", argv[]);
exit();
} WSADATA wsaData;
SOCKET hLinSock, hRecvSock;
SOCKADDR_IN lisnAdr, recvAdr;
LPWSAOVERLAPPED lpOvLp;
DWORD recvBytes;
LPPER_IO_DATA hbInfo;
int mode = , recvAdrSz, flagInfo = ; if (WSAStartup(MAKEWORD(, ), &wsaData) != )
ErrorHandling("WSAStartup() error."); hLinSock = WSASocket(PF_INET, SOCK_STREAM, , NULL, , WSA_FLAG_OVERLAPPED);
ioctlsocket(hLinSock, FIONBIO, (u_long*)&mode); // 套接字改成非阻塞的 memset(&lisnAdr, , sizeof(lisnAdr));
lisnAdr.sin_family = AF_INET;
lisnAdr.sin_addr.s_addr = htonl(INADDR_ANY);
lisnAdr.sin_port = htons(atoi(argv[])); if (bind(hLinSock, (SOCKADDR*)&lisnAdr, sizeof(lisnAdr)) == SOCKET_ERROR)
ErrorHandling("bind() error.");
if (listen(hLinSock, ) == SOCKET_ERROR)
ErrorHandling("listen() error.");
printf("Server start...\n");
recvAdrSz = sizeof(recvAdr);
while ()
{
SleepEx(, TRUE); // 让线程处于等待接收操作系统消息的线程状态
hRecvSock = accept(hLinSock, (SOCKADDR*)&recvAdr, &recvAdrSz);
if (hRecvSock == INVALID_SOCKET){
if (WSAGetLastError() == WSAEWOULDBLOCK)
continue;
else
ErrorHandling("accept() error");
}
puts("Client connected..."); lpOvLp = (LPWSAOVERLAPPED)malloc(sizeof(WSAOVERLAPPED));
memset(lpOvLp, , sizeof(lpOvLp)); hbInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
hbInfo->hClntSock = (DWORD)hRecvSock;
(hbInfo->wsaBuf).buf = hbInfo->buf;
(hbInfo->wsaBuf).len = BUF_SIZE; lpOvLp->hEvent = (HANDLE)hbInfo;
WSARecv(hRecvSock, &(hbInfo->wsaBuf), , &recvBytes, (LPDWORD)&flagInfo, lpOvLp, ReadCompRoutine);
}
closesocket(hRecvSock);
closesocket(hLinSock);
WSACleanup();
return ;
} void CALLBACK ReadCompRoutine(DWORD dwError, DWORD szRecvBytes, LPWSAOVERLAPPED lpOverlapped, DWORD flags)
{
LPPER_IO_DATA hbInfo = (LPPER_IO_DATA)(lpOverlapped->hEvent);
SOCKET hSock = hbInfo->hClntSock;
LPWSABUF bufInfo = &(hbInfo->wsaBuf);
DWORD sentBytes; if (szRecvBytes == )
{
closesocket(hSock);
free(hbInfo);
free(lpOverlapped);
puts("Client disconnected...");
}
else
{
bufInfo->len = szRecvBytes;
WSASend(hSock, bufInfo, , &sentBytes, , lpOverlapped, WriteCompRoutine);
}
} void CALLBACK WriteCompRoutine(DWORD dwError, DWORD szSendBytes, LPWSAOVERLAPPED lpOverlapped, DWORD flags)
{
LPPER_IO_DATA hbInfo = (LPPER_IO_DATA)(lpOverlapped->hEvent);
SOCKET hSock = hbInfo->hClntSock;
LPWSABUF bufInfo = &(hbInfo->wsaBuf);
DWORD recvBytes;
int flagInfo = ;
WSARecv(hSock, bufInfo, , &recvBytes, (LPDWORD)&flagInfo, lpOverlapped, ReadCompRoutine);
} void ErrorHandling(char *message) {
fputs(message, stderr);
fputc('\n', stderr);
}

二、IOCP回声服务端

服务端:

 #include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <WinSock2.h>
#include <windows.h> #define BUF_SIZE 128
#define READ 3
#define WRITE 5
void ErrorHandling(char *message);
unsigned int WINAPI EchoThreadMain(LPVOID pComPort); typedef struct // socket info
{
SOCKET hClntSock;
SOCKADDR_IN clntAdr;
}PER_HANDLE_DATA, *LPPER_HANDLE_DATA; typedef struct // buffer info
{
OVERLAPPED overlapped;
WSABUF wsaBuf;
char buffer[BUF_SIZE];
int rwMode; // read or write
}PER_IO_DATA, *LPPER_IO_DATA; int main(int argc, char *argv[])
{
if (argc != ) {
printf("Usage : %s <port>\n", argv[]);
exit();
} WSADATA wsaData;
HANDLE hComPort;
SYSTEM_INFO sysInfo;
LPPER_IO_DATA ioInfo;
LPPER_HANDLE_DATA handleInfo; SOCKET hServSock;
SOCKADDR_IN servAdr;
int recvBytes, i, flags = ; if (WSAStartup(MAKEWORD(, ), &wsaData) != )
ErrorHandling("WSAStartup() error."); hComPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, , );
GetSystemInfo(&sysInfo);
for (int i = ; i < (int)sysInfo.dwNumberOfProcessors; i++)
_beginthreadex(NULL, , EchoThreadMain, (LPVOID)hComPort, , NULL); hServSock = WSASocket(AF_INET, SOCK_STREAM, , NULL, , WSA_FLAG_OVERLAPPED);
memset(&servAdr, , sizeof(servAdr));
servAdr.sin_family = AF_INET;
servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
servAdr.sin_port = htons(atoi(argv[])); bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr));
listen(hServSock, ); puts("Server start...");
while (){
SOCKET hClntSock;
SOCKADDR_IN clntAdr;
int addrLen = sizeof(clntAdr); hClntSock = accept(hServSock, (SOCKADDR*)&clntAdr, &addrLen);
handleInfo = (LPPER_HANDLE_DATA)malloc(sizeof(PER_HANDLE_DATA));
handleInfo->hClntSock = hClntSock;
memcpy(&(handleInfo->clntAdr), &clntAdr, addrLen); CreateIoCompletionPort((HANDLE)hClntSock, hComPort, (DWORD)handleInfo, ); ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
memset(&(ioInfo->overlapped), , sizeof(OVERLAPPED));
ioInfo->wsaBuf.len = BUF_SIZE;
ioInfo->wsaBuf.buf = ioInfo->buffer;
ioInfo->rwMode = READ;
WSARecv(handleInfo->hClntSock, &(ioInfo->wsaBuf), , (LPDWORD)&recvBytes, (LPDWORD)&flags, &(ioInfo->overlapped), NULL);
} WSACleanup();
return ;
} unsigned int WINAPI EchoThreadMain(LPVOID pComPort)
{
HANDLE hComPort = (HANDLE)pComPort;
SOCKET sock;
DWORD bytesTrans;
LPPER_HANDLE_DATA handleInfo;
LPPER_IO_DATA ioInfo;
DWORD flags = ;
while ()
{
GetQueuedCompletionStatus(hComPort, &bytesTrans, (LPDWORD)&handleInfo, (LPOVERLAPPED*)&ioInfo, INFINITE);
sock = handleInfo->hClntSock;
if (ioInfo->rwMode == READ)
{
puts("message received!");
if (bytesTrans == ) // 传输EOF
{
closesocket(sock);
free(handleInfo);
free(ioInfo);
continue;
}
memset(&(ioInfo->overlapped), , sizeof(OVERLAPPED));
ioInfo->wsaBuf.len = bytesTrans;
ioInfo->rwMode = WRITE;
WSASend(sock, &(ioInfo->wsaBuf), , NULL, , &(ioInfo->overlapped), NULL);
ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
memset(&(ioInfo->overlapped), , sizeof(OVERLAPPED));
ioInfo->wsaBuf.len = BUF_SIZE;
ioInfo->wsaBuf.buf = ioInfo->buffer;
ioInfo->rwMode = READ;
WSARecv(sock, &(ioInfo->wsaBuf), , NULL, &flags, &(ioInfo->overlapped), NULL);
}
else{
puts("message sent");
free(ioInfo);
}
}
} void ErrorHandling(char *message) {
fputs(message, stderr);
fputc('\n', stderr);
}

windows—IOCP的更多相关文章

  1. windows IOCP 实践

    关于 windows IOCP 有人说 windows IOCP 是 windows 上最好的东西. IOCP 是真正的异步 IO,意味着每次发起一个 IO 请求,该调用本身则立即返回, 而包括 IO ...

  2. windows IOCP入门的一些资料

    最近需要看一个中间件的IOCP处理模块,需要了解这方面的知识 https://www.codeproject.com/articles/13382/a-simple-application-using ...

  3. 再次写给VC++ Windows开发者

    距离我的上一篇文章--写给VC++ Windows开发的初学者已经4年多时间过去了,感慨于时光如梭之余,更感慨于这么多年来(从1998年我初学VC 算起吧)到如今其实我仍然还只是个初学者而已.看看之前 ...

  4. EQueue - 一个纯C#写的分布式消息队列介绍2

    一年前,当我第一次开发完EQueue后,写过一篇文章介绍了其整体架构,做这个框架的背景,以及架构中的所有基本概念.通过那篇文章,大家可以对EQueue有一个基本的了解.经过了1年多的完善,EQueue ...

  5. [原创]直播服务器简单实现 http_flv和hls 内网直播桌面

    直播都不陌生了,如今主流的协议分析的对比图,个人见解. 协议 httpflv rtmp hls dash 传输层 http流 tcp流 http http 视频格式 flv flv tag Ts文件 ...

  6. libeventReferenceManual阅读笔记

    一.01_intro.html Example:A low-level ROT13 server with Libevent 这是一个利用event实现的server实例 Example:A simp ...

  7. 系统间通信(5)——IO通信模型和JAVA实践 下篇

    7.异步IO 上面两篇文章中,我们分别讲解了阻塞式同步IO.非阻塞式同步IO.多路复用IO 这三种IO模型,以及JAVA对于这三种IO模型的支持.重点说明了IO模型是由操作系统提供支持,且这三种IO模 ...

  8. Linux Native Aio 异步AIO的研究

    Linux Native Aio 异步AIO的研究 http://rango.swoole.com/archives/282 首先声明一下epoll+nonblock从宏观角度可以叫做全异步,但从微观 ...

  9. IO设计模式:Reactor和Proactor对比

    IO设计模式:Reactor和Proactor对比 平时接触的开源产品如Redis.ACE,事件模型都使用的Reactor模式:而同样做事件处理的Proactor,由于操作系统的原因,相关的开源产品也 ...

随机推荐

  1. MySQL 压缩文件安装遇到的问题及解决方案

    第一步:从官网下载压缩文件(链接). 第二步:解压该文件,放置到想放到的位置.我的目录是在 C:\mysql\mysql-8.0.12-winx64 下. 第三步:在C:\mysql\mysql-8. ...

  2. 利用Python计算π的值,并显示进度条

    利用Python计算π的值,并显示进度条  第一步:下载tqdm 第二步;编写代码 from math import * from tqdm import tqdm from time import ...

  3. 前端框架bootstrap(响应式布局)入门

    Bootstrap,是基于HTML,CSS.javascript的前端框架 该框架已经预定义了一套CSS样式和与样式相对应的js代码(对应的样式有对应的特效.) 开发人员只需要编写HTML结构,添加b ...

  4. [C++ Primer Plus] 第10章、对象和类(一)程序清单——辨析三个const

    程序清单10.1+10.2+10.3 头文件stock.h #ifndef STOCK00_H_ //先测试x是否被宏定义过 #define STOCK00_H_ //如果没有宏定义,就宏定义x并编译 ...

  5. maven中引入oracle驱动报错Missing artifact com.oracle:ojdbc14:jar:10.2.0.4.0

    转自https://blog.csdn.net/lovesomnus/article/details/49512777 在maven中央库中查找ojdbc,发现最新的版本是10.2.0.4.0,然后在 ...

  6. P1582 倒水

    传送门 思路: 类似于 袁绍的刁难 , 一道二进制的模拟题. 先将:将原先的瓶子数 n 转换成二进制,二进制中 1 的个数就是合并后剩下的瓶子个数 . 主要利用树状数组的 lowbit 函数: inl ...

  7. Mysql 索引之B+tree

    InnoDB使用的是聚簇索引,将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶 ...

  8. tensorboard

    在控制台输入: C:\Users\sunli\Documents\name\src>tensorboard --logdir=./w

  9. snakemake使用小结

    首先在linux 里配置conda 下载 wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.3.1-Linu ...

  10. [Shiro] tutorial 1 :SecurityManager and Subject

    SecurityManager是Shiro的绝对核心,不同于java.lang.SecurityManager,每个应用程序都要有一个SecurityManager. 所以我们第一件事就是配置一个Se ...