当前位置: 首页 > wzjs >正文

网站开发播放大视频卡顿北海 网站建设 公司

网站开发播放大视频卡顿,北海 网站建设 公司,网站建设中提示页面,中国风网站模板下载目录 引言 一、WSAAsyncSelect模型概述 二、WSAAsyncSelect模型流程 2.1 自定义消息 2.2 创建窗口例程 2.3 初始化套接字 2.4 注册网络事件 2.5 绑定和监听 2.6 消息循环 三、完整示例代码 引言 在网络编程的广袤天地中,高效处理网络事件是构建稳定应用的…

目录

引言

一、WSAAsyncSelect模型概述

二、WSAAsyncSelect模型流程

2.1 自定义消息

2.2 创建窗口例程

2.3 初始化套接字

2.4 注册网络事件

2.5 绑定和监听

2.6 消息循环

三、完整示例代码


引言

        在网络编程的广袤天地中,高效处理网络事件是构建稳定应用的关键。WSAAsyncSelect模型作为一种独特且实用的网络编程模型,为开发者提供了异步处理网络事件的有力手段。它巧妙地将Windows窗口消息机制与套接字相结合,让应用程序能够基于消息通知,及时响应各类网络事件。接下来,让我们深入探究WSAAsyncSelect模型的工作原理、具体流程以及在实际编程中的应用,一同解锁其在网络编程领域的强大潜力。

一、WSAAsyncSelect模型概述

        Windows 套接字异步选择模型,要是想在应用程序里用上WSAAsyncSelect模型,第一步就是用CreateWindow函数创建一个窗口,紧接着得给这个窗口配备一个窗口回调函数(WinProc)。除了创建窗口,使用对话框也是可行的,这种情况下就得给对话框配上对话框回调函数。

        WinSock给出了一个特别好用的异步I/O模型。依靠这个模型,应用程序可以在某个套接字上,接收那些基于Windows消息的网络事件通知。

        WSAAsyncSelect模型的实现办法是这样的:调用WSASyncSelect函数,这么做会自动把套接字切换到非阻塞模式,与此同时,还能注册一个或者多个你关心的网络事件。它会把套接字、窗口句柄以及自定义消息捆绑到一块儿。只要之前注册的网络事件发生了,对应的窗口就会收到一个基于消息的通知 。

二、WSAAsyncSelect模型流程

2.1 自定义消息

        用户需要自定义一个消息。当相关网络事件消息出现时,这个自定义消息会被发送到消息队列中。一般有以下两种自定义消息的方式:
1. 静态注册消息:

#define WM_MYSOCKETMSG WM_USER + 100; //具体查看自定义消息的范围

2. 动态注册消息:

#define MYWN_SOCKET L"MYWN_SOCK" //自定义一个字符串
UINT g_nNetMsgID = RegisterWindowMessage(MYWN_SOCKET);

2.2 创建窗口例程

        利用WSAAsyncSelect()函数开发WinSock应用程序,离不开Windows窗口。在窗口实例中接收用户自定义的消息。以Win32应用程序为例:

HWND g_SockHwnd = NULL; //接收SOCKET消息的窗口句柄
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) {HWND hWnd;hInst = hInstance; //将实例句柄存储在全局变量中hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);g_SockHwnd = hWnd;if (!hWnd)return FALSE;ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);return TRUE;
}

2.3 初始化套接字

        初始化组件和创建套接字的方法之前已经介绍过。

#include"winsock2.h"
#pragma comment(lib,"WS2_32.lib")
WSADATA stcData;
int nResult = 0;
nResult = WSAStartup(MAKEWORD(2, 2), &stcData);
//2.创建套接字
SOCKET sSocket = socket(AF_INET, SOCK_STREAM, 0);

2.4 注册网络事件

        WSAAsyncSelect函数有两个主要作用,一是它能自动把套接字设置成非阻塞模式,二是会给套接字关联上一个窗口句柄。一旦有网络事件出现,比如连接建立、数据发送或接收等情况发生,WSAAsyncSelect函数就会把相关信息发送到之前绑定的那个窗口。这样,应用程序在接收到像是连接、发送、接收这类网络通知时,对应的具体信息就会被投放到窗口消息队列当中 。

int WSAAsyncSelect(SOCKET s,         //套接字句柄HWND hWnd,        //要响应事件的窗口句柄unsigned int wMsg, //自定义的消息long lEvent       //注册的网络事件
);

         注:其中窗口句柄是在创建主窗口时获得的。注册网络事件通常在创建时设定连接通知和关闭通知。
(1)FD_READ事件触发条件:
    - 在数据到达socket后,并且前一个recv()调用完毕。
    - 调用recv()后,缓冲区还有未读完的数据时,还会继续响应该事件。
(2)FD_WRITE事件触发条件:
    - 第一次connect()或accept()后(即连接建立后)。
    - 调用send()返回WSAEWOULDBLOCK错误后,再次调用send()或sendto函数成功时。
(3)FD_ACCEPT事件触发条件:当有请求建立连接,并且前一个accept()调用后。
(4)FD_CLOSE事件触发条件:自己或客户端中断连接后。
(5)FD_CONNECT事件触发条件:调用了connect(),并且连接建立后。
示例:

WSAAsyncSelect(sSocket,g_SockHwnd,  g_nNetMsgID,    //当前服务端的SOCK句柄//当前服务端的窗口句柄//当有网络事件响应时窗口接收的消息FD_ACCEPT | FD_CLOSE);//需要响应的网络事件消息

2.5 绑定和监听

1. 初始化地址定址:

sockaddr_in sAddr = {0};
sAddr.sin_family = AF_INET;
sAddr.sin_port = htons(1234);
sAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

2. 绑定:

int nRet = 0;
nRet = bind(sSocket,(sockaddr*)&sAddr,sizeof(sockaddr_in));
//接收返回信息
//当前客户端SOCK句柄
//IP定址
//IP定址结构体大小

3. 监听:

nRet = listen(sSocket, SOMAXCONN);
//当前服务端的SOCK句柄
//等待连接的最大队列长度

2.6 消息循环

在消息循环中实现自定义消息的处理过程。

WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

当网络事件消息抵达一个窗口回调函数后:
- `message`为当前自定义消息。
- `wParam`为当前响应网络事件的套接字。
- `lParam`的高16位为错误码,低16位为具体的网络事件。
通过以下宏来获取相关信息:
- `WSAGETSELECTERROR`:返回`lParam`高字位包含的错误信息。
- `WSAGETSELECTEVENT`:根据得到的`lParam`的低字部分确定具体是哪一类网络事件。


示例代码:

int lError = WSAGETSELECTERROR(lParam); //高16位表示错误码
int lEvent = WSAGETSELECTEVENT(lParam);  //低字节为发生的网络事件
SOCKET MsgSocket = (SOCKET)wParam;       //消息事件
switch (lEvent) {
case FD_ACCEPT:sockaddr_in ClientAddr = {};int nClientLength = sizeof(ClientAddr);SOCKET sClientSock = accept(MsgSocket,//客户端地址信息//客户端地址信息长度//当前服务端的SOCK句柄(sockaddr*)&ClientAddr, &nClientLength);//设置消息模式WSAAsyncSelect(sClientSock, g_SockHwnd, g_nNetMsgID,FD_READ | FD_WRITE | FD_CLOSE);
}

接收不到网络事件的原因
        1. 在同一个套接字上,自定义的网络事件窗口消息被多次调用WSAAsyncSelect()函数注册不同的网络事件,这种情况下以最后一次注册的网络事件为准。例如:

WSAAsyncSelect(s, hWnd, wm_msg, FD_READ);
WSAAsyncSelect(s, hWnd, wm_msg, FD_ACCEPT);

        2. 在同一个套接字上多次调用WSAAsyncSelect()函数,且使用了不同的网络事件窗口消息。例如:

WSAAsyncSelect(s, hWnd, wm_msg1, FD_READ);
WSAAsyncSelect(s, hWnd, wm_msg2, FD_READ);

以下是示例代码部分:

#include "WSAAsyncSelect.h"
UINT g_nNetMsgID = 0;
HWND g_SockHwnd = NULL;
SOCKET g_sClientSock = NULL;
//套接字消息
//接收SOCKET消息的窗口句柄
//客户端Socket句柄
#define WM_MYSOCKETMSG WM_USER + 100;
BOOL AsyncSelectTCP() {//1.初始化套接字WSADATA stcData;int nResult = 0;nResult = WSAStartup(MAKEWORD(2, 2), &stcData);if (nResult == SOCKET_ERROR)return FALSE;g_nNetMsgID = RegisterWindowMessage(MYWN_SOCKET);//2.创建套接字SOCKET sSocket = Socket(AF_INET, SOCK_STREAM, 0);//3.注册感兴趣的网络事件//注册消息//当前服务端的SOCK句柄int nRet = WSAAsyncSelect(sSocket, g_SockHwnd,//当前服务端的窗口句柄g_nNetMsgID,//当有网络事件响应时窗口接收的消息FD_ACCEPT | FD_CLOSE);//需要响应的网络事件消息if (nRet) {MessageBox(NULL, L"", L"在监听SOCKET上设置网络消息失败", MB_OK);goto CloseSock;}//4.初始化地址定址sockaddr_in sAddr = {0};sAddr.sin_family = AF_INET;sAddr.sin_port = htons(1234);sAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//5.绑定nRet = bind(sSocket,(sockaddr*)&sAddr,sizeof(sockaddr_in));//当前客户端SOCK句柄//IP定址//IP定址结构体大小if (SOCKET_ERROR == nRet) {MessageBox(NULL, L"", L"绑定到指定地址端口出错!", MB_OK);goto CloseSock;}//6.监听  在调用WSAAsyncSelect后sSocket已经是非阻塞模式nRet = listen(sSocket,            //当前服务端的SOCK句柄SOMAXCONN);          //等待连接的最大队列长度if (SOCKET_ERROR == nRet) {MessageBox(NULL, L"错误", L"SOCKET进入监听模式出错!", MB_OK);goto CloseSock;}return TRUE;
CloseSock:closesocket(sSocket);WSACleanup();return FALSE;
}
//************************************
//函数名称: SocketMsg响应网络事件消息
//返回值:
//参数:
//参数:
//参数:
//参数:
//************************************
void SocketMsg(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {int iError = WSAGETSELECTERROR(lParam);int lEvent = WSAGETSELECTEVENT(lParam);SOCKET MsgSocket = (SOCKET)wParam;switch (lEvent) {//高16位表示错误码//低字节为发生的网络事件//响应消息事件的套接字case FD_ACCEPT: {sockaddr_in ClientAddr = {};int nClientLength = sizeof(ClientAddr);//客户端地址信息长度if (!g_sClientSock)   //当前例子只允许连接一个客户端{g_sClientSock = accept(MsgSocket,   //当前服务端的SOCK句柄(sockaddr*)&ClientAddr,&nClientLength);//重新为该消息设置网络事件WSAAsyncSelect(sClientSock, g_SockHwnd, g_nNetMsgID,FD_READ | FD_WRITE | FD_CLOSE);}break;}case FD_CLOSE: {closesocket(g_sClientSock);}break;case FD_READ:char szBufTmp[1024] = {0};if (g_sClientSock) {int iRecv = recv(MsgSocket, szBufTmp, 1024, 0);if (SOCKET_ERROR == iRecv || 0 == iRecv) {if (WSAEWOULDBLOCK == WSAGetLastError())Sleep(20);//停20ms}else {//显示信息}}break;}
}

在`XXX主窗口.cpp`文件中:
        1. 在`InitInstance`函数中创建窗口时,保存该窗口句柄:

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) {HWND hWnd;hInst = hInstance; //将实例句柄存储在全局变量中hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);g_SockHwnd = hWnd;if (!hWnd) {return FALSE;}ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);return TRUE;
}


        2. 在窗口回调函数中判断当前消息是否为自定义消息:

if (g_nNetMsgID == message) {SocketMsg(hWnd, message, wParam, lParam);
}

        WSAAsyncSelect模型通过将套接字与窗口消息机制相结合,为网络编程提供了一种异步处理网络事件的方式,在实际应用中有助于提升程序对网络事件的响应效率和处理能力 。

 

三、完整示例代码

TCP客户端代码:

待补充

- 这是一个基础的TCP客户端实现
- 主要功能:
  - 连接到服务器(127.0.0.1:0x1234)
  - 使用多线程处理接收消息
  - 通过控制台输入发送消息
  - 基本的错误处理 

WSAAsyncSelect模型服务端:

待补充

 这是一个基于Windows消息机制的TCP服务器实现
- 主要特点:
  - 使用WSAAsyncSelect实现异步通信
  - 通过Windows消息机制处理网络事件
  - 支持多客户端连接
  - 使用自定义消息(WM_MYSOCKET)处理网络事件
  - 在界面上显示连接状态和消息

 

 


文章转载自:

http://wa9agqMf.qmfhh.cn
http://mX6945AV.qmfhh.cn
http://HvWDM9RL.qmfhh.cn
http://NiuRxya1.qmfhh.cn
http://nmVBdGdm.qmfhh.cn
http://bJeWhj6S.qmfhh.cn
http://fsTlJmWG.qmfhh.cn
http://fE8gAO5E.qmfhh.cn
http://PnTCtfQz.qmfhh.cn
http://XQEa284R.qmfhh.cn
http://A6wlSEm9.qmfhh.cn
http://A6lMzrWR.qmfhh.cn
http://tEZbIaaT.qmfhh.cn
http://jKF9waWS.qmfhh.cn
http://QU33GOmj.qmfhh.cn
http://s75ZE2nT.qmfhh.cn
http://oAc3XZKV.qmfhh.cn
http://cai1MAhX.qmfhh.cn
http://wDGELIDS.qmfhh.cn
http://25KHlnSo.qmfhh.cn
http://eHrxeJuT.qmfhh.cn
http://HEHbz4vI.qmfhh.cn
http://lTDRbomt.qmfhh.cn
http://FoqJDhsk.qmfhh.cn
http://LbBy5rGc.qmfhh.cn
http://5HBRj5jD.qmfhh.cn
http://dnKIoriY.qmfhh.cn
http://97GalGhP.qmfhh.cn
http://NtfgPZbO.qmfhh.cn
http://C93oct5X.qmfhh.cn
http://www.dtcms.com/wzjs/769648.html

相关文章:

  • 大连h5网站建设自己制作app的应用程序
  • 少林寺网站谁做的电脑网站显示安全证书有问题怎么解决
  • 国外网站在国内做镜像站点python做h5网站
  • 泰安建设工程招聘信息网站wordpress搭建在线教育
  • 做进口产品的网站注册公司登陆哪个网站
  • 如何制作个人作品网站东莞常平医院
  • 京东这样的网站怎么做福州seo公司排名
  • 集团网站开发专业网页制作什么价格
  • 自己做的网站服务器开了进不去精美网站建设
  • 网站广告设计做网站月薪
  • 佛山新网站建设机构摄影网站 蜂鸟
  • 免费浏览网站的软件wordpress批量修改引用网址
  • 推广型的网站怎么做wordpress seo h1标签
  • 深圳市宝安区建设工程交易中心seo排名优化代理
  • 滨海新区商城网站建设领优惠券的网站是怎么做的
  • 密云区社区建设网站沧州工商联网站建设
  • 效果图网站源码关于网站建设分类
  • 企业推广是什么意思网站seo推广招聘
  • 淄博高端网站建设乐达wordpress页面的添加
  • 做企业门户网站要准备哪些内容网站建设服务器环境配置
  • 北京建网站公司哪家便宜赤峰建设淘宝网站
  • 象山专业网站建设旅游网站开发的目的和意义
  • 做网站版权所有怎么写免费校园网站建设
  • cms仿站网站被百度惩罚
  • 网站的建设可以起到什么作用是什么意思o2o网站开发相关技术
  • 做中文网站的公司做兼职哪个网站比较好
  • 教育机构网站是wordpress首页优化缩略图
  • 深圳龙华建网站公司vr看房制作软件
  • 网站备案 法人代表宁波北仑做公司网站
  • 镇江企业网站设计开发价格如何用服务器做网站