3.远程控制网络编程的设计上

RemoteCtrl.cpp

// RemoteCtrl.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include "pch.h"
#include "framework.h"
#include "RemoteCtrl.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif// 唯一的应用程序对象CWinApp theApp;using namespace std;      int main()
{int nRetCode = 0;HMODULE hModule = ::GetModuleHandle(nullptr);if (hModule != nullptr){// 初始化 MFC 并在失败时显示错误if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0)){// TODO: 在此处为应用程序的行为编写代码。wprintf(L"错误: MFC 初始化失败\n");nRetCode = 1;}else{// TODO: socket//套接字初始化WSADATA data;WSAStartup(MAKEWORD(1, 1), &data); //TODO:返回值处理SOCKET serv_sock = socket(PF_INET, SOCK_STREAM, 0); //使用TCP//TODO:校验,不一定创建成功了sockaddr_in serv_adr;memset(&serv_adr, 0, sizeof(serv_adr)); //给清0一下serv_adr.sin_family = AF_INET;serv_adr.sin_addr.s_addr = INADDR_ANY;serv_adr.sin_port = htons(9527);//绑定bind(serv_sock, (sockaddr*)&serv_adr, sizeof(serv_adr)); //TODO//TODO:listen(serv_sock, 1); //控制端是1对1的char buffer[1024];recv(serv_sock, buffer, sizeof(buffer), 0);send(serv_sock, buffer, sizeof(buffer), 0);closesocket(serv_sock);WSACleanup();}}else{// TODO: 更改错误代码以符合需要wprintf(L"错误: GetModuleHandle 失败\n");nRetCode = 1;}return nRetCode;
}

接下来我们想着去优化代码

WSAStartup()WSACleanup() 函数是固定的,一个在程序初始化时候执行,一个在程序销毁时候执行,那么有没有一种东西,可以完成这种操作,有的,静态变量。

静态变量是在首次被调用时候初始化,在程序销毁时候销毁,全局的静态函数会在main函数之前初始化,在main函数返回之后销毁。

在main函数之前执行,是多线程环境还是单线程环境?

单线程环境,单线程不存在上锁解锁互斥之类的

套路化代码

但是我们这是一个MFC工程,我们需要考虑不是所有操作都需要到main函数里面实现,有些操作可以在main函数之前完成,有些可以在main函数返回以后完成,静态全局变量满足这个需求,我们需要添加一个自己的类

编辑器细节1

Snipaste_2024-10-18_00-52-20

添加类和添加类向导的区别,一个是添加自己的类,一个是添加MFC的类

image-20250907223615764

添加上CServerSocket全局静态类(独立于main之外),在构造函数里面添加上套接字的初始化函数,在析构函数里面添加上套接字的清理函数

#pragma once
#include "pch.h"
#include "framework.h"class CServerSocket
{
public:CServerSocket(){if (InitSockEnv() == FALSE) {MessageBox(NULL, _T("无法初始化套接字环境,请检查网络设置!"), _T("初始化错误!"), MB_OK | MB_ICONERROR);exit(0);}}~CServerSocket() {WSACleanup();}BOOL InitSockEnv() {WSADATA data;if (WSAStartup(MAKEWORD(1, 1), &data) != 0) { //TODO:返回值处理}return FALSE;}return TRUE;}
};extern CServerSocket server;

为什么添加pch.hframework.h头文件?因为有些网络编程的头文件在这框架的头文件里面

那么我们怎么在RemoteCtrl.cpp文件里面用上这个全局静态类呢?

因为**声明可以多次,定义只能一次。**所以我们在ServerSocket.cpp里面定义一个ServerSocket类的对象

然后在头文件里面靠extern这个对象,来让外面包含这个头文件时候使用(被多次包含也没有关系,因为可以多次声明)

extern int i; //声明,不是定义
int i; //声明,也是定义

然后我们需要明确一点的是进main之前,我们肯定是单线程,开天辟地前的井井有条,到main,我们可能开始需要定义多线程,然后退出main时也只剩下一个进程了,毁天灭地后的井井有条

代码如下:

int main()
{int nRetCode = 0;//int a;HMODULE hModule = ::GetModuleHandle(nullptr);if (hModule != nullptr){// 初始化 MFC 并在失败时显示错误if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0)){// TODO: 在此处为应用程序的行为编写代码。wprintf(L"错误: MFC 初始化失败\n");nRetCode = 1;}else{ // TODO: 在此处为应用程序的行为编写代码。server;WSADATA data;SOCKET serv_sock = socket(PF_INET, SOCK_STREAM, 0); //TCP//TODO:校验sockaddr_in serv_adr, client_adr;memset(&serv_adr, 0, sizeof(serv_adr));serv_adr.sin_family = AF_INET;serv_adr.sin_addr.s_addr = INADDR_ANY; //服务器可能有4个IP等,监听所有地址,被控机子不只有yserv_adr.sin_port = htons(9527);//绑定bind(serv_sock, (sockaddr*)&serv_adr, sizeof(serv_adr)); //TODO//TODO:listen(serv_sock, 1); //控制端是1对1的char buffer[1024];//int cli_sz = sizeof(client_adr);//SOCKET client = accept(serv_sock, (sockaddr*)&client_adr,&cli_sz)//recv(serv_sock, buffer, sizeof(buffer), 0);//send(serv_sock, buffer, sizeof(buffer), 0);closesocket(serv_sock);//全局的静态变量}}

当下还没有解决的问题:

要是别人继续定义一个CServerSocket的局部对象,进去后又执行一道构造函数,退出时候提前执行了析构函数,那么网络环境全部乱套了

下一篇文章就是要用单例模式来解决这个问题

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

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

相关文章

毕业设计|基于Python的课程智能问答系统

4系统设计4.1功能模块设计对本系统进行全面的系统功能的分析,可以得出基于Python《Python程序设计》课程智能问答系统的功能模块图,如图4-1所示。图4-1 系统功能模块图4.2数据库设计4.2.1数据库设计原则学习程序设计时,若想要深入理解数据库管…

iOS原生开发和Flutter开发的看法

这是一个技术选型的问题。作为一名同时精通iOS原生和Flutter的开发者,我的看法是:这不是一个“二选一”的问题,而是一个“如何根据场景做最佳选择”的问题。 它们不是替代关系,而是互补关系。以下是我对两者的对比和看法&#xff…

docker桌面版 镜像配置

配置内容 Docker Engine配置*(截止2025年09月10日能用) {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-mirrors": [&q…

Java 面向对象基础初步

Java 面向对象基础初步 面向对象的核心概念概览 面向对象的核心目标是 把数据和操作封装在一起(对象),并通过抽象、继承与多态组织程序。简而言之,我们总是没法回避程序设计的四个话题: 封装(Encapsulation…

反向代理技术

一、核心比喻:公司的总机前台 想象一下一家大公司: 客户:想联系公司里的某位员工(比如技术部的张三)。公司的总机号码(唯一公开的号码):比如 400-123-4567。前台:接听总机…

数据整理器(Data Collators)(90)

数据整理器(Data Collators) 数据整理器(Data Collators) 导致问题的“罪魁祸首”,往往是长度不一的序列。 指令格式 关键术语说明 数据整理器(Data Collators) 数据整理器负责将多个数据样本拼接成一个迷你批次(mini-batch)。它通常处于“隐形”状态——每次使用PyT…

PySpark EDA 完整案例介绍,附代码(三)

本篇文章Why Most Data Scientists Are Wrong About PySpark EDA — And How to Do It Right适合希望高效处理大数据的从业者。文章的亮点在于强调了使用PySpark进行探索性数据分析(EDA)的重要性,避免了将Spark数据框转换为Pandas的低效做法。…

leetcode18(无重复字符的最长子串)

给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串 的长度。示例 1:输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。思路:对于长度为0的数组单独处理其他数组最小的可能…

计算机毕设 java 高校家教平台 基于 SSM 框架的高校家教服务平台 Java+MySQL 的家教预约与课程管理系统

计算机毕设java高校家教平台75snd9 (配套有源码 程序 mysql数据库 论文)本套源码可以先看具体功能演示视频领取,文末有联xi 可分享在高校家教需求增长的背景下,传统家教对接依赖线下中介、信息分散,存在沟通成本高、课…

【自记】Python 的 SQLAlchemy 完整实践教程

目录 SQLAlchemy 介绍环境准备与安装数据库连接数据模型定义基本数据操作复杂查询操作高级特性实战项目示例性能优化与最佳实践常见问题与解决方案 1. SQLAlchemy 介绍 1.1 什么是SQLAlchemy SQLAlchemy 是一个用于 Python 的 SQL 工具和对象关系映射(ORM&#x…

springboot rabbitmq 延时队列消息确认收货订单已完成

供应商后台-点击发货-默认3天自动收货确认&#xff0c;更新订单状态已完成。1 pom.xml 引入依赖&#xff1a;<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>2 …

Linux内核TCP输出引擎:深入解析数据传输的核心机制

引言 传输控制协议(TCP)作为互联网最重要的基础协议之一,其实现质量直接关系到网络性能和应用体验。在Linux内核中,TCP协议的输出引擎是实现可靠数据传输的核心组件,负责将应用层数据高效、可靠地传输到网络对端。本文将深入分析Linux内核中TCP输出引擎的关键机制和实现原…

数据仓库详解

数据仓库详解第一节 数据仓库构建方法论和实践一、数据仓库与数据库的区别二、数据仓库对于企业的价值三、数据仓库的模型构建1、数据仓库构建需要考虑的问题2、什么是数仓的数据模型3、如何构建数仓的数据模型&#xff08;1&#xff09;概念模型设计&#xff08;2&#xff09;…

单身杯1(web)

web签到<?php# -*- coding: utf-8 -*- # Author: h1xa # Date: 2022-03-19 12:10:55 # Last Modified by: h1xa # Last Modified time: 2022-03-19 13:27:18 # email: h1xactfer.com # link: https://ctfer.comerror_reporting(0); highlight_file(__FILE__);$file $_…

RNN/LSTM/GRU/Transformer

RNN的局限1&#xff1a;长期依赖&#xff08;Long-TermDependencies&#xff09;问题但是同样会有一些更加复杂的场景。比如我们试着去预测“I grew up in France...I speak fluent French”最后的词“French”。当前的信息建议下一个词可能是一种语言的名字&#xff0c;但是如…

浏览器开发CEFSharp+X86 (十六)网页读取电子秤数据——仙盟创梦IDE

一、东方仙盟智能浏览器&#xff1a;跨平台&#xff0c;畅连百种硬件&#xff0c;速启现场编译东方仙盟 VOS 智能浏览器在网页调用硬件 SDK 领域堪称卓越典范。它全面兼容多平台&#xff0c;无论是电脑、手机还是各类移动终端&#xff0c;都能完美适配&#xff0c;无缝对接。令…

腾讯云EdgeOne免费套餐:零成本开启网站加速与安全防护

腾讯云EdgeOne免费套餐&#xff1a;零成本开启网站加速与安全防护 ​一键解锁全球3200节点&#xff0c;让网站速度提升53%&#xff0c;同时获得企业级安全防护作为一名站长或个人开发者&#xff0c;你是否曾为网站加载速度缓慢而苦恼&#xff1f;是否担心网站遭遇DDoS攻击或恶意…

服务器数据恢复—Raid6阵列崩溃导致上层分区无法访问的数据恢复案例

服务器存储数据恢复环境&#xff1a; 一台infortrend某型号存储&#xff0c;存储设备上有12块硬盘&#xff0c;组建一组raid6磁盘阵列。阵列上层有一个lun&#xff0c;映射到WINDOWS系统上使用。WINDOWS系统划分了一个GUID Partition Table分区。服务器存储故障&#xff1a; 存…

【生产故事会】Kafka 生产环境参数优化实战案例

Kafka 3.9.1 生产环境参数优化实战案例(8核32G HDD场景) 一、背景与硬件/业务配置 某企业级全链路日志采集平台需构建高稳定Kafka集群,承担核心业务日志流转(涵盖用户行为、系统监控、交易链路日志),单集群3节点部署,硬件与业务特征如下: 维度 具体配置 硬件配置 C…

推荐 Eclipse Temurin 的 OpenJDK

推荐 Eclipse Temurin 的 OpenJDK 发行版 https://adoptium.net/zh-CN/temurin/releases&#xff0c;是基于其在技术可靠性、生态中立性、许可友好性和社区支持等多个维度的综合优势。 以下是详细的原因&#xff0c;解释了为什么 Eclipse Temurin 通常是基于 OpenJDK 构建的 J…