一、重叠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. linux windows 格式化一块大于2 TiB硬盘

    转自:https://help.aliyun.com/document_detail/34377.html?spm=a2c4g.11186623.2.10.17447386JrLBNR#concept ...

  2. Gitlab安装、汉化及使用

    环境:centos 关闭防火墙和selinux [root@Gitlab ~]# setenforce [root@Gitlab ~]# service iptables stop && ...

  3. 爬坑系列----Redis查询key报空指针异常,而redis中确实存在该key

    现象: 1.在A方法中根据key查询一个list,可以获取到相应的值 2.在B方法中同样调用此方法,传入相同的key,查询不到值,为null,报空指针异常 起初我也一脸懵逼,到现在虽然解决了,还是不知 ...

  4. 动态令牌验证遇到的问题(判断用户长按backspace键)

    因为最近负责泰康项目的前端工作,他们的登录需要进行安全验证,也就是所谓的双因素验证,即在OA平台登录过后,还需要安全部门发送安全令牌进行验证.令牌验证效果如下: 主要功能有:1.默认第一项focus. ...

  5. 0 vs null

    看图说话 0 如图所示: 0 表示有纸(值), 但是纸(值)是0. 所以取纸(值)的时可以取, 但是没法用. null 如图所示: null 表示没有纸(值), 是真的啥都没有, 现在你抽纸的时候会出 ...

  6. Docker Swarm Mode 学习笔记(创建 Swarm 集群)

    Swarm 集群由管理节点与工作节点组成. 初始化集群 使用命令:docker swarm init 如果你的 Docker 主机有多个网卡, 拥有多个 IP 地址, 必须使用 --advertise ...

  7. Go-常见的面试题(一)

    文章转载地址:https://juejin.im/entry/5971bed66fb9a06bb21adf15 1.写出下面代码的输出 package main import "fmt&qu ...

  8. TP5创建动态数据表

    $sql = " CREATE TABLE IF NOT EXISTS `$table_name` (`id` int(11) unsigned NOT NULL AUTO_INCREMEN ...

  9. 用Python实现简单通讯录

    一个简单的通讯录例子 #!/usr/bin/python __author__ = 'fierce' #coding:utf-8 import os #引用os模块 import pickle #应用 ...

  10. h5视频播放

    h5视频播放 一直在写js原生的东西,感觉总是停滞不前,现在我们应该学一些h5新的特性,因为我们毕竟是从事前端的,下面我们一起来写一个视频播放吧 1,html <div class=" ...