WSAAsyncSelect模型
时间:2022-04-22
本文章向大家介绍WSAAsyncSelect模型,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
WSAAsyncSelect模型允许程序以windows消息的形式接受网络事件通知
WSAAsyncSelect函数自动把套接字设为非阻塞模式,并且为套接字绑定一个窗口句柄,当有网络事件发生时,便向这个窗口发送消息
int WSAAsyncSelect(
SOCKET s, //套接字句柄
HWND hWnd,//指定一个窗口句柄
u_int wMsg,//网络事件到来的消息ID
long lEvent//指定那些需要发送
);
FD_READ:接收对方发送的数据包
FD_WRITE:继续发送数据
FD_ACCEPT:有连接进入
FD_CONNECT:连接对方主机
FD_CLOSE:连接被关闭
调用WSAAsyncSelect函数监听套接字
::WSAAsyncSelect(sListen,hWnd,WM_SOCKET,FD_ACCEPT|FD_CLOSE);
成功调用后,应用程序开始以windows消息形式在窗口函数接受网络事件通知
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT uMsg,
WPARAM wParam,//发送网络事件的套接字句柄
LPARAM lParam//指定了发生的网络事件
);
下面是简单的TCP服务器程序,接受客户端的连接请求,打印出接收的数据。
// WSATCPSERVER.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"WS2_32")
class CInitSock
{
public:
CInitSock(BYTE minorVer=2,BYTE majorVer=2)
{
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer,majorVer);
if(::WSAStartup(sockVersion,&wsaData)!=0)
{
exit(0);
}
}
~CInitSock()
{
::WSACleanup();
}
};
CInitSock initSock;
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
int _tmain(int argc, _TCHAR* argv[])
{
char szClassName[] = "MainWClass";
WNDCLASSEX wndclass;
//用描述主窗口的参数填充WNDCLASSEX结构
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc = WindowProc;
wndclass.cbWndExtra = 0;
wndclass.cbClsExtra = 0;
wndclass.hInstance = NULL;
wndclass.hIcon = ::LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor = ::LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szClassName;
wndclass.hIconSm = NULL;
::RegisterClassEx(&wndclass);
//创建主窗口
HWND hWnd = ::CreateWindowEx(
0,
szClassName,
"",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
NULL,
NULL);
if(hWnd == NULL)
{
::MessageBox(NULL,"创建窗口出错!","error",MB_OK);
return -1;
}
USHORT nPort = 4567;
SOCKET sListen = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(nPort);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
if(::bind(sListen,(sockaddr*)&sin,sizeof(sin)) == SOCKET_ERROR)
{
printf("Failed bind()n");
return -1;
}
//套接字设为窗口通知消息类型
::WSAAsyncSelect(sListen,hWnd,WM_SOCKET,FD_ACCEPT|FD_CLOSE);
::listen(sListen,5);
//消息队列中取出消息
MSG msg;
while(::GetMessage(&msg,NULL,0,0))
{
::TranslateMessage(&msg);//转化键盘消息
::DispatchMessage(&msg);//将消息发送到相应窗口函数
}
return msg.wParam;//当GETMESSAGE返回0时结束
}
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_SOCKET:
{
SOCKET s=wParam;
//查看是否出错
if(WSAGETSELECTERROR(lParam))
{
::closesocket(s);
return 0;
}
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
{
SOCKET client = ::accept(s,NULL,NULL);
::WSAAsyncSelect(client,hWnd,WM_SOCKET,FD_READ|FD_WRITE|FD_CLOSE);
}
break;
case FD_WRITE:
{
}
break;
case FD_READ:
{
char szText[1024]={0};
if(::recv(s,szText,1024,0) == -1)
::closesocket(s);
else
printf("接收数据:%s",szText);
}
break;
case FD_CLOSE:
{
::closesocket(s);
}
break;
}
}
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
//不处理的消息交给系统默认处理
return ::DefWindowProc(hWnd,uMsg,wParam,lParam);
}
好多错误啊...首先 char 不能转成LPSZ 其次,WM_SOCKET不认,为什么......哎
- 用了Docker,妈妈再也不担心我的软件安装了 - 基础篇
- 适配器模式(Adapter)
- 敞开的地狱之门:Kerberos协议的滥用
- CY7C68013A的一点总结
- RxJava2 实战(1) - 后台执行耗时操作,实时通知 UI 更新
- AutoIt木马又一发:暗藏神秘照片
- css3动画从入门到精通
- ReactJs和React Native的那些事
- Linux学习-文件排序和FASTA文件操作
- Bash漏洞再次演进:缓冲区溢出导致远程任意命令执行
- Pandas,让Python像R一样处理数据,但快
- ViewPager 实现 Galler 效果, 中间大图显示,两边小图展示
- 最小生成树-Prim算法和Kruskal算法
- Bash漏洞批量检测工具与修复方案
- 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 数组属性和方法
- JS根据列表排列对象数组
- git提取两次提交或者版本的差异文件并打包成zip压缩包
- 博客通用版Live2d伊斯特瓦尔发布
- 一个小需求,自动重启k8s集群中日志不刷新的POD
- 多图,一文了解 8 种常见的数据结构
- Jenkins--pipline 流水线部署Java后端项目
- 微信小程序修炼之路LV1—工具介绍篇
- CentOS 7 部署OpenLDAP+FreeRadius
- 手把手教你使用yolo进行对象检测
- K8s之Helm工具详解
- 技术创作101训练营——上古神器Gvim--从入门到精通
- 关于linux7下编写crontab任务执行mysqldump备份无效
- 黑暗中的YOLO:解决黑夜里的目标检测 | ECCV 2020
- Elasticsearch:Java 运用示例
- 【5分钟玩转Lighthouse】搭建个人云盘