一、重叠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. Centos 7 磁盘阵列配置介绍(RAID)

    转自:https://blog.51cto.com/gaowenlong/2086918 Centos 7 磁盘阵列配置介绍每当我们提到磁盘阵列,相信广大管理员并不陌生,比如我们一般安装服务器系统的时 ...

  2. Docker+Teamcity+Maven+SVN搭建持续集成环境

    这是使用Jenkins作为CI/CD工具,Teamcity的作用是相同的.

  3. 【shell】awk按域去除重复行

    首先解释一下什么叫“按域去除重复行”: 有的时候我们需要去除的重复行并不是整行都重复,两行的其中一列的元素相同我们有的时候就需要认定这两行重复,因此有了今天的内容. 去除重复行shell有一个原生命令 ...

  4. Servlet3.0与springmvc那些事

    官方文档:https://docs.spring.io/spring/docs/5.0.2.RELEASE/spring-framework-reference/web.html#mvc-servle ...

  5. 为git关联编辑器(比如notepad++) Associating text editors with Git

    Associating text editors with git Using Notepad++ as your editors you can set your default editor in ...

  6. git忽略对已入库文件的修改

    项目开发过程中,会遇到本地配置文件每个开发人员不同的情况,但如果遇到类似数据库配置这种最终需要加入 git 版本控制的配置,则会陷入两难境地.要么不跟踪,要么有人提交后其他人同步下来必须手动修改,非常 ...

  7. maven 安装本地jar

    mvn install:install-file -Dfile=D:/open-api-sdk-2.0.jar -DgroupId=com.jd.open -DartifactId=jd-api-sd ...

  8. scala链接mysql

    方法一:链接并操作mysql //链接Mysqlval driver = "com.mysql.jdbc.Driver"val url = "jdbc:mysql://1 ...

  9. .Net dependent configuration

    error info: 解决方案:在.exe.config文件中配置Newtonsoft.Json所用版本 <runtime> <assemblyBinding xmlns=&quo ...

  10. js之作用域链到闭包

    一.作用域 全局作用域和函数作用域(局部作用域). 一个变量的作用域就是源代码中定义这个变量的区域. 二.作用域链和闭包 全局变量只有一个(window,globel),全局环境下每一个函数都会形成一 ...