windows异步通知I/O模型
回声服务器端:
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h> #define BUF_SIZE 1024
void ErrorHandling(char *message);
void CompressSockets(SOCKET hSockArr[], int idx, int total);
void CompressEvents(WSAEVENT hEventArr[], int idx, int total); int main(int argc, char *argv[])
{
if (argc != ) {
printf("Usage : %s <port>\n", argv[]);
exit();
} WSADATA wsaData;
SOCKET hServSock, hClntSock;
SOCKADDR_IN servAdr, clntAdr; SOCKET hSockArr[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT hEventArr[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT newEvent;
WSANETWORKEVENTS netEvents; int numOfClntSock = ;
int strLen;
int posInfo, startIdx;
int clntAdrLen;
char msg[BUF_SIZE]; if (WSAStartup(MAKEWORD(, ), &wsaData) != )
ErrorHandling("WSAStartup() error."); hServSock = socket(PF_INET, SOCK_STREAM, );
if (hServSock == INVALID_SOCKET)
ErrorHandling("socket() error."); memset(&servAdr, , sizeof(servAdr));
servAdr.sin_family = AF_INET;
servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
servAdr.sin_port = htons(atoi(argv[])); if (bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
ErrorHandling("bind() error.");
if (listen(hServSock, ) == SOCKET_ERROR)
ErrorHandling("listen() error."); newEvent = WSACreateEvent();
if (WSAEventSelect(hServSock, newEvent, FD_ACCEPT) == SOCKET_ERROR)
ErrorHandling("WSAEventSelect() error."); hSockArr[numOfClntSock] = hServSock;
hEventArr[numOfClntSock] = newEvent;
numOfClntSock++;
printf("Server start...\n");
while ()
{
posInfo = WSAWaitForMultipleEvents(numOfClntSock, hEventArr, FALSE, WSA_INFINITE, FALSE);
startIdx = posInfo - WSA_WAIT_EVENT_0;
for (int i = startIdx; i < numOfClntSock; i++){
int sigEventIdx = WSAWaitForMultipleEvents(, &hEventArr[i], TRUE, , FALSE);
if (sigEventIdx == WSA_WAIT_FAILED || sigEventIdx == WSA_WAIT_TIMEOUT){
continue;
}
else{
sigEventIdx = i;
WSAEnumNetworkEvents(hSockArr[sigEventIdx], hEventArr[sigEventIdx], &netEvents);
if (netEvents.lNetworkEvents & FD_ACCEPT){ // 客户端请求连接
if (netEvents.iErrorCode[FD_ACCEPT_BIT] != )
{
printf("Accept error.\n");
break;
}
clntAdrLen = sizeof(clntAdr);
hClntSock = accept(hSockArr[sigEventIdx], (SOCKADDR*)&clntAdr, &clntAdrLen);
newEvent = WSACreateEvent();
WSAEventSelect(hClntSock, newEvent, FD_READ | FD_CLOSE); hEventArr[numOfClntSock] = newEvent;
hSockArr[numOfClntSock] = hClntSock;
numOfClntSock++;
printf("connected new client...\n");
}
if (netEvents.lNetworkEvents & FD_READ){ // 接收数据
if (netEvents.iErrorCode[FD_READ_BIT] != )
{
printf("Read error\n");
break;
}
strLen = recv(hSockArr[sigEventIdx], msg, sizeof(msg), );
send(hSockArr[sigEventIdx], msg, strLen, );
}
if (netEvents.lNetworkEvents & FD_CLOSE){ // 断开连接
if (netEvents.iErrorCode[FD_CLOSE_BIT] != )
{
printf("Close Error.\n");
break;
}
WSACloseEvent(hEventArr[sigEventIdx]);
closesocket(hSockArr[sigEventIdx]); numOfClntSock--;
CompressSockets(hSockArr, sigEventIdx, numOfClntSock);
CompressEvents(hEventArr, sigEventIdx, numOfClntSock);
}
}
}
}
WSACleanup();
return ;
} void ErrorHandling(char *message) {
fputs(message, stderr);
fputc('\n', stderr);
} void CompressSockets(SOCKET hSockArr[], int idx, int total){
for (int i = idx; i < total; i++)
hSockArr[i] = hSockArr[i + ];
} void CompressEvents(WSAEVENT hEventArr[], int idx, int total){
for (int i = idx; i < total; i++)
hEventArr[i] = hEventArr[i + ];
}
客户端:
#pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h> #define BUF_SIZE 1024
void ErrorHandling(char *message); int main(int argc, char* argv[]) {
if (argc != ) {
printf("Usage : %s <IP> <port>\n", argv[]);
exit();
} WSADATA wsaData;
SOCKET sock;
SOCKADDR_IN serverAddr;
char message[BUF_SIZE];
int sLen, recvLen; if (WSAStartup(MAKEWORD(, ), &wsaData) != )
ErrorHandling("WSAStartup() error"); sock = socket(PF_INET, SOCK_STREAM, );
if (sock == INVALID_SOCKET)
ErrorHandling("socket() error"); memset(&serverAddr, , sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(argv[]);
serverAddr.sin_port = htons(atoi(argv[])); if (connect(sock, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
ErrorHandling("connect() error");
else
printf("Connected.......\n");
while ()
{
fputs("Input message(Q to quit):", stdout);
fgets(message, BUF_SIZE, stdin);
if (!strcmp(message, "q\n") || !strcmp(message, "Q\n"))
break;
sLen = send(sock, message, strlen(message), );
recvLen = ;
while (recvLen < sLen) {
int cnt = recv(sock, message, BUF_SIZE - , );
if (cnt == -)
ErrorHandling("ercv() error");
recvLen += cnt;
}
message[recvLen] = ;
printf("Message from server: %s\n", message);
}
closesocket(sock);
WSACleanup();
return ;
} void ErrorHandling(char *message) {
fputs(message, stderr);
fputc('\n', stderr);
}
windows异步通知I/O模型的更多相关文章
- c++ 网络编程(十) LINUX/windows 异步通知I/O模型与重叠I/O模型 附带示例代码
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9662931.html 一.异步IO模型(asynchronous IO) (1)什么是异步I/ ...
- windows 异步通知I/O模型与重叠I/O模型
一.异步IO模型(asynchronous IO) (1)什么是异步I/O 异步I/O(asynchronous I/O)由POSIX规范定义.演变成当前POSIX规范的各种早起标准所定义的实时函数中 ...
- 第三十四篇:在SOUI中使用异步通知
概述 异步通知是客户端开发中常见的需求,比如在一个网络处理线程中要通知UI线程更新等等. 通常在Windows编程中,为了方便,我们一般会向UI线程的窗口句柄Post/Send一个窗口消息从而达到将非 ...
- Linux的fasync驱动异步通知详解【转】
本文转载自:http://blog.csdn.net/coding__madman/article/details/51851338 版权声明:本文为博主原创文章,未经博主允许不得转载. 工作项目用有 ...
- Paip.Php Java 异步编程。推模型与拉模型。响应式(Reactive)”编程FutureData总结... 1
Paip.Php Java 异步编程.推模型与拉模型.响应式(Reactive)"编程FutureData总结... 1.1.1 异步调用的实现以及角色(:调用者 提货单) F ...
- 蜕变成蝶~Linux设备驱动之异步通知和异步I/O
在设备驱动中使用异步通知可以使得对设备的访问可进行时,由驱动主动通知应用程序进行访问.因此,使用无阻塞I/O的应用程序无需轮询设备是否可访问,而阻塞访问也可以被类似“中断”的异步通知所取代.异步通知类 ...
- OS信号实现Java异步通知
OS信号实现Java异步通知本文将结合操作系统的信号机制,来尝试实现一个简单的,不依赖功能环境的Java异步通知功能.没有特殊说明,本文所有的示例,都是基于Linux.信号简介信号是在软件层次上对中断 ...
- 嵌入式Linux驱动学习之路(十三)按键驱动-异步通知
之前的按键方式: 查询: 极度占用CPU资源 中断: 在读的时候产生休眠,在没有信号的时候永远不会返回. poll机制: 在中断的基础上加上超时时间. 异步通知就是通过信号来传送. 首先在应用程序中有 ...
- Linux学习 :按键信号 之 异步通知
一.异步通知概念: 异步通知是指:一旦设备就绪,则主动通知应用程序,应用程序根本就不需要查询设备状态,类似于中断的概念,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是异步的,一个进 ...
随机推荐
- GO值类型与引用类型
值类型 值类型包括基本数据类型,int,float,bool,string,以及数组和结构体(struct). 值类型变量声明后,不管是否已经赋值,编译器为其分配内存,此时该值存储于栈上. 值类型的默 ...
- C# 多笔数据导入DB
6万笔数据瞬间导入进DB 命名空间 using NPOI.HSSF.UserModel; using NPOI.XSSF.UserModel; //Filename为文件路径 public JsonR ...
- mysql_study_3
代码: CREATE DATABASE test_01; CREATE DATABASE mysql_shiyan; use mysql_shiyan; CREATE TABLE department ...
- MySQL_Key值(MUL、PRI、NUL)
查询表结构: mysql> describe cc; +----------+-----------+------+-----+---------+-------+ | Field | Type ...
- React Native之遇到的问题
问题一:使用 Android Studio 运行 React Native 新项目时,报错:Unable to load script from assets 'index.android.bundl ...
- textspan 转连接
import 'package:flutter/material.dart'; import 'package:flutter/gestures.dart'; import 'package:url_ ...
- Mac提醒休息软件Stretchly(很好用)
github地址: https://github.com/hovancik/stretchly 安装就不介绍了,他的自定义时间目前还是有点麻烦,介绍一下. 配置文件是 ~/Library/Applic ...
- Numpy 基础
Numpy 基础 参考https://www.jianshu.com/p/83c8ef18a1e8 import numpy as np 简单创建数组 # 创建简单列表 a = [1, 2, 3, 4 ...
- 编码原则 之 Stable Dependencies
The Stable Dependencies Principle states that “The dependencies between software packages should be ...
- c语言程序操作