实现基于IOCP的回声服务器端
时间:2019-11-15
本文章向大家介绍实现基于IOCP的回声服务器端,主要包括实现基于IOCP的回声服务器端使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <process.h> 4 #include <winsock2.h> 5 #include <windows.h> 6 7 #define BUF_SIZE 1024 8 #define READ 3 9 #define WRITE 5 10 11 typedef struct //socket info 12 { 13 SOCKET hClntSock; 14 SOCKADDR_IN clntAdr; 15 }PER_HANDLE_DATA, *LPPER_HANDLE_DATA; 16 17 typedef struct //buffer info 18 { 19 OVERLAPPED overlapped; 20 WSABUF wsaBuf; 21 char buffer[BUF_SIZE]; 22 int rwMode; // READ or WRITE 23 }PER_IO_DATA, *LPPER_IO_DATA; 24 25 unsigned WINAPI EchoThreadMain(LPVOID CompletionPortIO); 26 void ErrorHanding(char *msg); 27 28 int main(int argc, char *argv[]) 29 { 30 WSADATA wsaData; 31 HANDLE hComPort; 32 SYSTEM_INFO sysInfo; 33 LPPER_IO_DATA ioInfo; 34 LPPER_HANDLE_DATA handleInfo; 35 36 SOCKET hServSock; 37 SOCKADDR_IN servAdr; 38 int recvBytes, i, flags = 0; 39 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) 40 ErrorHanding("WSAStartUp() error!"); 41 42 hComPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); 43 GetSystemInfo(&sysInfo); 44 for (i = 0; i < sysInfo.dwNumberOfProcessors; i++) 45 _beginthreadex(NULL, 0, EchoThreadMain, (LPVOID)hComPort, 0, NULL); 46 47 hServSock = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); 48 memset(&servAdr, 0, sizeof(servAdr)); 49 servAdr.sin_family = AF_INET; 50 servAdr.sin_addr.s_addr = htonl(INADDR_ANY); 51 servAdr.sin_port = htons(atoi(argv[1])); 52 53 bind(hServSock, (SOCKADDR *)&servAdr, sizeof(servAdr)); 54 listen(hServSock, 5); 55 56 while (1) 57 { 58 SOCKET hClntSock; 59 SOCKADDR_IN clntAdr; 60 int addrLen = sizeof(clntAdr); 61 62 hClntSock = accept(hServSock, (SOCKADDR *)&servAdr, &addrLen); 63 handleInfo = (LPPER_HANDLE_DATA)malloc(sizeof(PER_HANDLE_DATA)); 64 handleInfo->hClntSock = hClntSock; 65 memcpy(&(handleInfo->clntAdr), &clntAdr, addrLen); 66 67 CreateIoCompletionPort((HANDLE)hClntSock, hComPort, (DWORD)handleInfo, 0); 68 69 ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA)); 70 memset(&(ioInfo->overlapped), 0, sizeof(OVERLAPPED)); 71 ioInfo->wsaBuf.len = BUF_SIZE; 72 ioInfo->wsaBuf.buf = ioInfo->buffer; 73 ioInfo->rwMode = READ; 74 WSARecv(handleInfo->hClntSock, &(ioInfo->wsaBuf), 1, (LPDWORD)&recvBytes, (LPDWORD)&flags, &(ioInfo->overlapped), NULL); 75 } 76 return 0; 77 } // end of main function 78 79 unsigned WINAPI EchoThreadMain(LPVOID pComPort) 80 { 81 HANDLE hComPort = (HANDLE)pComPort; 82 SOCKET sock; 83 DWORD bytesTrans; 84 LPPER_HANDLE_DATA handleInfo; 85 LPPER_IO_DATA ioInfo; 86 DWORD flags = 0; 87 88 while (1) 89 { 90 GetQueuedCompletionStatus(hComPort, &bytesTrans, (LPDWORD) &handleInfo, (LPOVERLAPPED *) &ioInfo, INFINITE); 91 sock = handleInfo->hClntSock; 92 93 if (ioInfo->rwMode == READ) 94 { 95 puts("message received!"); 96 if (bytesTrans == 0) 97 { 98 closesocket(sock); 99 free(handleInfo); 100 free(ioInfo); 101 continue; 102 } 103 104 memset(&(ioInfo->overlapped), 0, sizeof(OVERLAPPED)); 105 ioInfo->wsaBuf.len = bytesTrans; 106 ioInfo->rwMode = WRITE; 107 WSASend(sock, &(ioInfo->wsaBuf), 1, NULL, 0, &(ioInfo->overlapped), NULL); 108 109 ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA)); 110 memset(&(ioInfo->overlapped), 0, sizeof(OVERLAPPED)); 111 ioInfo->wsaBuf.len = BUF_SIZE; 112 ioInfo->wsaBuf.buf = ioInfo->buffer; 113 ioInfo->rwMode = READ; 114 WSARecv(sock, &(ioInfo->wsaBuf), 1, NULL, &flags, &(ioInfo->overlapped), NULL); 115 } 116 else 117 { 118 puts("message sent!"); 119 free(ioInfo); 120 } 121 } 122 return 0; 123 } 124 125 void ErrorHanding(char *msg) 126 { 127 fputs(msg, stderr); 128 fputc('\n', stderr); 129 exit(1); 130 }
原文地址:https://www.cnblogs.com/wisdomroc/p/11867766.html
- 弹窗层效果的实现(非jQuery实现)
- 简单的导航栏实现
- js实现css3的过渡,需要注意的一点(浏览器优化)
- 居中详解
- 通过pl/sql计算程序的运行时间(r3笔记第77天)
- 操作系统存储管理和oracle数据库(第一篇) (r3笔记第76天)
- 关于虚拟索引的学习(r3笔记第75天)
- python数据挖掘:能不能找出吃货最佳住宿点?
- 解决ajax跨域请求 (总结)
- Python+Selenium+PIL+Tesseract真正自动识别验证码进行一键登录
- 在深度学习TensorFlow 框架上使用 LSTM 进行情感分析
- python玩微信:如何获得自己微信的好友统计信息
- 关于不可见索引的学习(r3笔记74天)
- 【专业技术第五讲】动态链接库及其用法
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- React环境搭建
- leetcode - 旋转数组的最小数字
- 笔记101 | 文件的压缩与解压笔记
- 诸葛亮vs司马懿,排序算法大战谁能笑到最后?
- Centos密钥登陆,解决云服务器被尝试登陆问题
- Fair Scheduler到Capacity Scheduler 转换工具
- 这可能是把SpringBoot配置文件讲解的最详细的文章了
- 抛出这8个问题,检验一下你到底会不会ThreadLocal,来摸个底~
- 最近合肥降雨不断,给自己做一个天气情况微信定时推送吧
- 【适合收藏】为了多点时间陪女朋友,我向BAT大佬跪求了这15条JS技巧
- iOS文本尺寸自适应异步计算实现
- CentOS7下系统分析与排障利器sysdig简单介绍
- Faker 一个生成虚拟数据的Python模块
- ICLR 2020 Mogrifier LSTM 解析
- 优秀的程序员是如何利用工具来提升工作效率的?