制作公司网站需要几个数据表/网络推广工作内容

制作公司网站需要几个数据表,网络推广工作内容,交友网站开发公司,安卓网站开发ui十、基于I/O模型的网络开发 10.9 事件选择模型 10.0.1 基本概念 事件选择(WSAEventSelect) 模型是另一个有用的异步 I/O 模型。和 WSAAsyncSelect 模 型类似的是,它也允许应用程序在一个或多个套接字上接收以事件为基础的网络事件通知,最 主要的差别在…

十、基于I/O模型的网络开发

10.9 事件选择模型

10.0.1 基本概念

事件选择(WSAEventSelect) 模型是另一个有用的异步 I/O 模型。和 WSAAsyncSelect 模 型类似的是,它也允许应用程序在一个或多个套接字上接收以事件为基础的网络事件通知,最 主要的差别在于网络事件会投递至一个事件对象句柄,而非投递到一个窗口例程。

10.9.2 WSAEventSelect函数

WSAEventSelect 模型主要由函数WSAEventSelect 来实现。注意,这里用了“主要由”, 说明还有其他配套函数一起辅助来实现这个模型。

后面会讲到其他函数。这里先看一下 WSAEventSelect。

WSAEventSelect 函数将一个已经创建好的事件对象(由WSACreateEvent 创建)与某个套 接字关联在一起,同时注册自己感兴趣的网络事件类型。WSAEventSelect 的函数声明如下:

int WSAAPI WSAEventSelect(SOCKET S,WSAEVENT hEventObject, long lNetworkEvents);
  • 其中,s 是套接字描述符;

  • hEventObject标识要与指定的网络事件集关联的事件对象的句 柄 ;

  • INetworkEvents指定应用程序感兴趣的网络事件组合的位掩码。

  • 如果函数成功,那么返回值为零;否则,将返回值SOCKET_ERROR, 并且可以通过调用 WSAGetLastError来获取特定的错误号。

  • 与select 和 WSAAsyncSelect 函数一样,WSAEventSelect 通常用于确定何时可以进行数据 收发操作(确定调用send或 recv能立即成功的时间点)。如果时间点没到,那么函数会返回 WSAEWOULDBLOCK, 此时我们要正确处理这个错误码。

10.9.3 实 战WSAEventSelect模型

事件选择模型的基本思路是:为感兴趣的一组网络事件创建一个事件对象,再调用 WSAEventSelect 函数将网络事件和事件对象关联起来。当网络事件发生时,Winsock 会使相 应的事件对象收到通知,在事件对象上等待的函数就会返回。之后,再调用 WSAEnumNetworkEvents函数便可获取发生了什么网络事件。
事件选择模型写的TCP 服务器实现的过程如下:

  • (1)创建事件对象和套接字。创建一个事件对象的方法是调用 WSACreateEvent 函数, 它的定义如下:
WSAEVENT WSAAPI WSACreateEvent();
  • 如果没有发生错误,那么函数将返回事件对象的句柄;

  • 否则,返回值为 WSA_INVALID_EVENT, 可以通过WSAGetLastError 函数获取更多的错误信息。这个事件对 象创建后,其初始状态为“未受信”,就是没有收到通知状态。

  • WSACreateEvent 创建的事件有两种工作状态以及两种工作模式:工作状态分别是“有信 号 " (signaled) 和“无信号" (nonsignaled), 工作模式包括“人工重设” (manual reset) 和“自动重设” (auto reset) 。WSACreateEvent 创建的事件开始是处于一种无信号的工作状 态,并用一种人工重设模式来创建事件句柄。

  • (2)将事件对象与套接字关联在一起,同时注册自己感兴趣的网络事件类型(FD_READ、 FD_WRITE、FD_ACCEPT、FD_CONNECT、FD_CLOSE 等),这个过程通过函数 WSAEventSelect实现。

  • (3)调用事件等待函数WSAWaitForMultipleEvents在所有事件对象上等待,该函数返回后,我们就可以确认在哪些套接字上发生了网络事件。 当一个或所有指定的事件对象处于信号状态、超时或执行了 I/O 完成例程时,函数 WSAWaitForMultipleEvents返回,该函数声明如下:

#include <winsock2.h>
#pragma comment(lib, "Ws232.lib")
DWORD WSAAPI WSAWaitForMultipleEvents(DWORD CEvents,const WSAEVENT *lphEvents, BOOL fWaitAll,DWORD dwTimeout,BOOL fAlertable);
  • cEvents: 表 示lphEvent 所指数组中的事件对象句柄数,事件对象句柄的最大数量是 WSA_MAXIMUM_WAIT_EVENTS, 必须指定一个或多个事件。
  • lphEvents: 指向事件对象句柄数组的指针,数组可以包含不同类型对象的句柄,如果 后面参数fWaitAll 设置为TRUE, 那么它不能包含同一句柄的多个副本,如果在等待 仍处于挂起状态时关闭其中一个句柄,那么WSAWaitForMultipleEvents 的行为将不 可知。另外,句柄必须具有同步访问权限。
  • fWaitAll: 输入参数,用于指定等待类型的值。如果赋值为TRUE, 那么当lphEvents 数组中所有对象的状态都处于有信号时,函数将返回。注意,是所有对象都处于信号 状态才返回。如果赋值为FALSE, 则当向任一事件对象发出信号时,函数返回。在 这一种情况下,返回值减去WSA_WAIT_EVENT_0 表示其状态导致函数返回的事件 对象的索引。如果在调用期间有多个事件对象发出信号,那么返回值指示信号事件对 象的lphEvents 数组索引的最小值。
  • dwTimeout: 超时时间,单位是毫秒。如果超时时间到,则函数返回,即使不满足 fWaitAll 参数指定的条件。如果 dw Timeout参数为零,则函数将测试指定事件对象的 状态并立即返回。如果dwTimeout 是 WSA_INFINITE, 则函数将永远等待。
  • fAlertable: 指定线程是否处于可警报的等待状态,以便系统可以执行I/O 完成例程。 如果为TRUE, 则线程将处于可警报的等待状态,并且当系统执行I/O 完成例程时, 函数可以返回。在这种情况下,将返回 WSA_WAIT_IO_COMPLETION, 并且尚未 发出正在等待的事件的信号。应用程序必须再次调用WSAWaitForMultipleEvents 函 数。如果为FALSE, 则线程不会处于可警报的等待状态,也不会执行I/O 完成例程。

如果函数成功,那么返回值为以下值之一:

  • WSA_WAIT_EVEN_0 到 (WSA_WAIT_EVENT_0+cEvents-1): 如果参数 fWaitAll 参数为 TRUE, 则返回值指示已向所有指定的事件对象发出信号。如果 fWaitAll 参数为FALSE, 则返回值减去WSA_WAIT_EVENT_0 表示其状态导致函数 返回的事件对象的索引。如果在调用期间有多个事件对象发出信号,则返回值指示信 号事件对象的lphEvents 数组索引的最小值。
  • WSA_WAIT_IO_COMPLETION:等待被执行的一个或多个I/O 完成例程结束。正在 等待的事件尚未发出信号,应用程序必须再次调用WSAWaitForMultipleEvents 函数。 只有fAlertable 参数为TRUE 时,才能返回此返回值。
  • WSA_WAIT_TIMEOUT: 超时间隔已过,并且未满足fWaitAll参数指定的条件,未
    执行任何I/O完成例程。

如果函数失败,则返回值为WSA_WAIT_FAILED。此时可以通过函数WSAGetLastError 获取更多错误码,常见错误码如下:

  • WSANOTINITIALISED: 在调用本API 之前应成功调用WSAStartup()。

  • WSAENETDOWN: 网络子系统失效。

  • WSA_NOT_ENOUGH_MEMORY: 无足够内存完成该操作。

  • WSA_INVALID_HANDLE:lphEvents 数组中的一个或多个值不是合法的事件对象句柄。

  • WSA_INVALID_PARAMETER:cEvents参数未包含合法的句柄数目。

  • (4)检测所指定套接字上发生网络事件,然后处理发生的网络事件,完毕继续在事件对 象上等待。检测所指定套接字上发生网络事件是通过函数WSAEnumNetworkEvents 来实现, 该函数声明如下:

#include <winsock2.h>
#pragma comment(lib, "Ws232.lib")int WSAAPI WSAEnumNetworkEvents(SOCKET s,WSAEVENT hEventObject,LPWSANETWORKEVENTS lpNetworkEvents);
  • s: 套接字描述符。
  • hEventObject: 标识要重置的关联事件对象的可选句柄。
  • lpNetworkEvents: 指 向WSANETWORKEVENTS 结构的指针,该结构由发生的网络 事件和任何相关错误代码的记录填充。

如果操作成功,函数返回值为零;否则,将返回值SOCKET ERROR, 并且可以通过调用WSAGetLastError来获取特定的错误码。

以上4步是使用事件选择模型的基本步骤。下面我们看一个实例。

服务端

#define _WINSOCK_DEPRECATED_NO_WARNINGS#include <winsock2.h>
#include <Windows.h>
#include <iostream>
#pragma comment(lib,"ws2_32.lib")using std::cout;
using std::cin;
using std::endl;
using std::ends;void WSAEventServerSocket()
{SOCKET server = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (server == INVALID_SOCKET) {cout << "创建SOCKET失败!,错误代码:" << WSAGetLastError() << endl;return;}int error = 0;sockaddr_in addr_in;addr_in.sin_family = AF_INET;addr_in.sin_port = htons(6000);addr_in.sin_addr.s_addr = INADDR_ANY;error = ::bind(server, (sockaddr*)&addr_in, sizeof(sockaddr_in));if (error == SOCKET_ERROR) {cout << "绑定端口失败!,错误代码:" << WSAGetLastError() << endl;return;}listen(server, 5);if (error == SOCKET_ERROR) {cout << "监听失败!,错误代码:" << WSAGetLastError() << endl;return;}cout << "成功监听端口 :" << ntohs(addr_in.sin_port) << endl;WSAEVENT eventArray[WSA_MAXIMUM_WAIT_EVENTS];        // 事件对象数组SOCKET sockArray[WSA_MAXIMUM_WAIT_EVENTS];            // 事件对象数组对应的SOCKET句柄int nEvent = 0;                    // 事件对象数组的数量 WSAEVENT event0 = ::WSACreateEvent();::WSAEventSelect(server, event0, FD_ACCEPT | FD_CLOSE);eventArray[nEvent] = event0;sockArray[nEvent] = server;nEvent++;while (true) {int nIndex = ::WSAWaitForMultipleEvents(nEvent, eventArray, false, WSA_INFINITE, false);if (nIndex == WSA_WAIT_IO_COMPLETION || nIndex == WSA_WAIT_TIMEOUT) {cout << "等待时发生错误!错误代码:" << WSAGetLastError() << endl;break;}nIndex = nIndex - WSA_WAIT_EVENT_0;WSANETWORKEVENTS event;SOCKET sock = sockArray[nIndex];::WSAEnumNetworkEvents(sock, eventArray[nIndex], &event);if (event.lNetworkEvents & FD_ACCEPT) {if (event.iErrorCode[FD_ACCEPT_BIT] == 0) {if (nEvent >= WSA_MAXIMUM_WAIT_EVENTS) {cout << "事件对象太多,拒绝连接" << endl;continue;}sockaddr_in addr;int len = sizeof(sockaddr_in);SOCKET client = ::accept(sock, (sockaddr*)&addr, &len);if (client != INVALID_SOCKET) {cout << "接受了一个客户端连接 " << inet_ntoa(addr.sin_addr) << ":" << ntohs(addr.sin_port) << endl;WSAEVENT eventNew = ::WSACreateEvent();::WSAEventSelect(client, eventNew, FD_READ | FD_CLOSE | FD_WRITE);eventArray[nEvent] = eventNew;sockArray[nEvent] = client;nEvent++;}}}else if (event.lNetworkEvents & FD_READ) {if (event.iErrorCode[FD_READ_BIT] == 0) {char buf[2500];ZeroMemory(buf, 2500);int nRecv = ::recv(sock, buf, 2500, 0);if (nRecv > 0) {cout << "收到一个消息 :" << buf << endl;char strSend[] = "hi,client,I am server, I recvived your message.";::send(sock, strSend, strlen(strSend), 0);}}}else if (event.lNetworkEvents & FD_CLOSE) {::WSACloseEvent(eventArray[nIndex]);::closesocket(sockArray[nIndex]);cout << "一个客户端连接已经断开了连接" << endl;for (int j = nIndex; j < nEvent - 1; j++) {eventArray[j] = eventArray[j + 1];sockArray[j] = sockArray[j + 1];}nEvent--;}else if (event.lNetworkEvents & FD_WRITE) {cout << "一个客户端连接允许写入数据" << endl;}} // end while::closesocket(server);
}int main(){WSADATA wsaData;int error;WORD wVersionRequested;wVersionRequested = WINSOCK_VERSION;error = WSAStartup(wVersionRequested, &wsaData);if (error != 0) {WSACleanup();return 0;}WSAEventServerSocket();WSACleanup();return 0;
}

客户端

#define _WINSOCK_DEPRECATED_NO_WARNINGS#include<stdlib.h>
#include<WINSOCK2.H>
#include <windows.h> 
#include <process.h>  #include<iostream>
#include<string>using namespace std;#define BUF_SIZE 64
#pragma comment(lib,"WS2_32.lib")void recv(PVOID pt)
{SOCKET  sHost = *((SOCKET*)pt);while (true){char buf[BUF_SIZE];//清空接收数据的缓冲区memset(buf, 0, BUF_SIZE);int retVal = recv(sHost, buf, sizeof(buf), 0);if (SOCKET_ERROR == retVal){int  err = WSAGetLastError();//无法立即完成非阻塞Socket上的操作if (err == WSAEWOULDBLOCK){Sleep(1000);//printf("\nwaiting  reply!");continue;}else if (err == WSAETIMEDOUT || err == WSAENETDOWN || err == WSAECONNRESET)//已建立连接{printf("recv failed!");closesocket(sHost);WSACleanup();return;}}Sleep(100);printf("\n%s", buf);//break;}
}int main()
{WSADATA wsd;SOCKET sHost;SOCKADDR_IN servAddr;//服务器地址int retVal;//调用Socket函数的返回值char buf[BUF_SIZE];//初始化Socket环境if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0){printf("WSAStartup failed!\n");return -1;}sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//设置服务器Socket地址servAddr.sin_family = AF_INET;servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//在实际应用中,建议将服务器的IP地址和端口号保存在配置文件中servAddr.sin_port = htons(6000);//计算地址的长度int sServerAddlen = sizeof(servAddr);//调用ioctlsocket()将其设置为非阻塞模式int iMode = 1;retVal = ioctlsocket(sHost, FIONBIO, (u_long FAR*) & iMode);if (retVal == SOCKET_ERROR){printf("ioctlsocket failed!");WSACleanup();return -1;}//循环等待while (true){//连接到服务器retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));if (SOCKET_ERROR == retVal){int err = WSAGetLastError();//无法立即完成非阻塞Socket上的操作if (err == WSAEWOULDBLOCK || err == WSAEINVAL){Sleep(1);printf("check  connect!\n");continue;}else if (err == WSAEISCONN)//已建立连接{break;}else{printf("connection failed!\n");closesocket(sHost);WSACleanup();return -1;}}}unsigned long threadId = _beginthread(recv, 0, &sHost);//启动一个线程接收数据的线程   while (true){//向服务器发送字符串,并显示反馈信息printf("input a string to send:\n");std::string str;//接收输入的数据std::cin >> str;//将用户输入的数据复制到buf中ZeroMemory(buf, BUF_SIZE);strcpy_s(buf, str.c_str());if (strcmp(buf, "quit") == 0){printf("quit!\n");break;}while (true){retVal = send(sHost, buf, strlen(buf), 0);if (SOCKET_ERROR == retVal){int err = WSAGetLastError();if (err == WSAEWOULDBLOCK){//无法立即完成非阻塞Socket上的操作Sleep(5);continue;}else{printf("send failed!\n");closesocket(sHost);WSACleanup();return -1;}}break;}}return 0;
}

参考书籍《Visual C++2017 网络编程实战》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/73197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 F407ZGT6开发板

#ifndef _tftlcd_H #define _tftlcd_H #include "system.h" //定义LCD彩屏的驱动类型 可根据自己手上的彩屏背面型号来选择打开哪种驱动 //#def…

江科大51单片机笔记【15】直流电机驱动(PWM)

写在前言 此为博主自学江科大51单片机&#xff08;B站&#xff09;的笔记&#xff0c;方便后续重温知识 在后面的章节中&#xff0c;为了防止篇幅过长和易于查找&#xff0c;我把一个小节分成两部分来发&#xff0c;上章节主要是关于本节课的硬件介绍、电路图、原理图等理论…

uniapp+Vue3 开发小程序的下载文件功能

小程序下载文件&#xff0c;可以先预览文件内容&#xff0c;然后在手机上打开文件的工具中选择保存。 简单示例&#xff1a;&#xff08;复制到HBuilder直接食用即可&#xff09; <template><view class"container-detail"><view class"example…

【分布式】聊聊分布式id实现方案和生产经验

对于分布式Id来说&#xff0c;在面试过程中也是高频面试题&#xff0c;所以主要针对分布式id实现方案进行详细分析下。 应用场景 对于无论是单机还是分布式系统来说&#xff0c;对于很多场景需要全局唯一ID&#xff0c; 数据库id唯一性日志traceId 可以方便找到日志链&#…

【性能测试】Jmeter如何做一份测试报告(3)

本篇文章主要介绍Jmeter中下载插件&#xff08;Jmeter Plugins&#xff09; 如何使用监听器插件&#xff0c;线程组插件&#xff0c;梯度压测线程组 测试报告需要去关注的数据&#xff0c;怎么看测试报告图表 目录 一&#xff1a;插件下载 1&#xff1a;下载地址 2&#xff…

cocos creator使用mesh修改图片为圆形,减少使用mask,j减少drawcall,优化性能

cocos creator版本2.4.11 一个mask占用drawcall 3个以上&#xff0c;针对游戏中技能图标&#xff0c;cd,以及多玩家头像&#xff0c;是有很大优化空间 1.上代码&#xff0c;只适合单独图片的&#xff0c;不适合在图集中的图片 const { ccclass, property } cc._decorator;c…

AI重构SEO关键词布局

内容概要 在搜索引擎优化&#xff08;SEO&#xff09;领域&#xff0c;AI技术的深度应用正在颠覆传统关键词布局逻辑。通过机器学习算法与语义分析模型&#xff0c;智能系统能够实时解析海量搜索数据&#xff0c;构建动态词库并精准捕捉用户意图。相较于依赖人工经验的关键词筛…

泛微ecode的页面开发发送请求参数携带集合

1.在开发过程中我们难免遇见会存在需要将集合传递到后端的情况&#xff0c;那么这里就有一些如下的注意事项&#xff0c;如以下代码&#xff1a; // 新增action.boundasync addQuestion(formData) {var theList this.questionAnswerList;var questionAnswerListArray new Ar…

20250212:linux系统DNS解析卡顿5秒的bug

问题: 1:人脸离线识别记录可以正常上传云端 2:人脸在线识别请求却一直超时 3:客户使用在线网络 思路:

道路运输安全员考试:备考中的心理调适与策略

备考道路运输安全员考试&#xff0c;心理调适同样重要。考试压力往往会影响考生的学习效率和考试发挥。​ 首先&#xff0c;要正确认识考试压力。适度的压力可以激发学习动力&#xff0c;但过度的压力则会适得其反。当感到压力过大时&#xff0c;要学会自我调节。可以通过运动…

LLM - 白话RAG(Retrieval-Augmented Generation)

文章目录 Pre一、大模型的"幻觉"之谜1.1 何为"幻觉"现象&#xff1f;1.2 专业场景的致命挑战 二、RAG技术解析&#xff1a;给大模型装上"知识外挂"2.1 核心原理&#xff1a;动态知识增强2.2 技术实现三部曲 三、RAG vs 微调&#xff1a;技术选型…

探索现代 C++:新特性、工程实践与热点趋势

目录 一、现代 C 的关键特性与热点关联 二、精简代码示例解析 三、工程实践中的应用思考 四、总结与展望 近几年&#xff0c;人工智能、边缘计算与跨语言开发成为技术热点&#xff0c;而 C 作为高性能系统编程的主力军&#xff0c;也在不断进化。从 C11 到 C20&#xff0c;…

257. 二叉树的所有路径(递归+回溯)

257. 二叉树的所有路径 力扣题目链接(opens new window) 给定一个二叉树&#xff0c;返回所有从根节点到叶子节点的路径。 说明: 叶子节点是指没有子节点的节点。 示例: 思路&#xff1a;在叶子节点收割结果&#xff0c;如果不是叶子节点&#xff0c;则依次处理左右子树&a…

CSDN博客:Markdown编辑语法教程总结教程(中)

❤个人主页&#xff1a;折枝寄北的博客 Markdown编辑语法教程总结 前言1. 列表1.1 无序列表1.2 有序列表1.3 待办事项列表1.4 自定义列表 2. 图片2.1 直接插入图片2.2 插入带尺寸的图片2.3 插入宽度确定&#xff0c;高度等比例的图片2.4 插入高度确定宽度等比例的图片2.5 插入居…

RK3588部署YOLOv8(2):OpenCV和RGA实现模型前处理对比

目录 前言 1. 结果对比 1.1 时间对比 1.2 CPU和NPU占用对比 2. RGA实现YOLO前处理 2.1 实现思路 2.2 处理类的声明 2.3 处理类的实现 总结 前言 RK平台上有RGA (Raster Graphic Acceleration Unit) 加速&#xff0c;使用RGA可以减少资源占用、加速图片处理速度。因此…

SNIPAR:快速实现亲缘个体的基因型分离与推断

SNIPAR&#xff1a;快速实现亲缘个体的基因型分离与推断 近日&#xff0c;英国剑桥大学研究团队在Nature Genetics上发表了最新研究成果——SNIPAR&#xff08;SNP-based Inference of Pedigree relationship, Ancestry, and Recombination&#xff09;。这一强大的工具可以帮助…

阿里云操作系统控制台评测:国产AI+运维 一站式运维管理平台

阿里云操作系统控制台评测&#xff1a;国产AI运维 一站式运维管理平台 引言 随着云计算技术的飞速发展&#xff0c;企业在云端的运维管理面临更高的要求。阿里云操作系统控制台作为一款集运维管理、智能助手和系统诊断等多功能于一体的工具&#xff0c;正逐步成为企业高效管理…

大语言模型学习--向量数据库Milvus实践

Milvus是目前比较流行的开源向量数据库&#xff0c;其官网地址 Milvus 是什么&#xff1f; | Milvus 文档 1.Milvus简介 Milvus 是一种高性能、高扩展性的向量数据库。Milvus 提供强大的数据建模功能&#xff0c;能够将非结构化或多模式数据组织成结构化的 Collections。它支…

Visual Studio 安装及使用教程(Windows)【安装】

文章目录 一、 Visual Studio 下载1. 官网下载2. 其它渠道 二、Visual Studio 安装三、Visual Studio 使用四、Visual Studio 其它设置1. 桌面快捷方式2. 更改主题、字体大小 软件 / 环境安装及配置目录 一、 Visual Studio 下载 1. 官网下载 安装地址&#xff1a;https://vi…

关于ngx-datatable no data empty message自定义模板解决方案

背景&#xff1a;由于ngx-dataable插件默认没有数据时显示的文案是no data to display&#xff0c;且没有任何样式。这里希望通过自定义模板来实现。但目前github中有一个案例是通过设置代码&#xff1a; https://swimlane.github.io/ngx-datatable/empty** <ngx-datatable…