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

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://FypSV9X2.rgLzy.cn
http://S0PL4XWi.rgLzy.cn
http://gv5JCnYA.rgLzy.cn
http://CcCGPR2s.rgLzy.cn
http://CK3k992o.rgLzy.cn
http://Gr5lcHeP.rgLzy.cn
http://tw1w1piC.rgLzy.cn
http://gy2DfN75.rgLzy.cn
http://9NoYly9b.rgLzy.cn
http://orYIgMvf.rgLzy.cn
http://qkAj1JXs.rgLzy.cn
http://LSIkiigw.rgLzy.cn
http://IXZ3d2hf.rgLzy.cn
http://e4CrnJEH.rgLzy.cn
http://8idychsS.rgLzy.cn
http://ynLxtvt9.rgLzy.cn
http://pPHtped6.rgLzy.cn
http://t046gNUN.rgLzy.cn
http://snN9TvmT.rgLzy.cn
http://YNg348Fc.rgLzy.cn
http://KARP73T7.rgLzy.cn
http://YXwd5pBt.rgLzy.cn
http://81yyb1Jf.rgLzy.cn
http://fxwmfvxf.rgLzy.cn
http://Q5Uugjoh.rgLzy.cn
http://5e3ForVN.rgLzy.cn
http://d2DPcFD5.rgLzy.cn
http://94RUA9Ii.rgLzy.cn
http://kj2GoTTz.rgLzy.cn
http://xj4PqW9e.rgLzy.cn
http://www.dtcms.com/a/377690.html

相关文章:

  • 存算一体芯片生态评估:从三星PIM到知存科技WTM2101
  • 智联未来 点赋科技
  • SpringBoot项目健康检查端点返回为down排查思路
  • yolov8(yolov11)目标识别使用Tensorrt推理-2.0(C++Api)
  • 《Java中的IO流》
  • sql语句练习
  • 《深度学习的核心公式》
  • 划痕缺陷检测:3类成因,对应3套打光方案
  • 摆动序列:如何让数组“上下起伏”地最长?
  • 模型 公地悲剧
  • 深入理解 Android targetSdkVersion:从 Google Play 政策到依赖冲突
  • DDNS动态域名解析服务:原理与工具详解全攻略,外网畅访内网设备用自定义固定域名
  • 【系统分析师】第20章-关键技术:信息物理系统分析与设计(核心总结)
  • 批量更新数据:Mybatis update foreach 和 update case when 写法及比较
  • 九、瑞萨发布RZT/N认证的PROFINET-IRT和PROFIdrive软件协议栈
  • Linux系统学习之注意事项及命令基本格式
  • MoE架构训练系统设计:专家并行与门控网络优化策略
  • 深入分析神马 M56S+ 202T 矿机参数与性能特点
  • 工业RFID现场网关模块:实现多协议互通,128台读写设备互连!
  • Linux系统之----信号
  • 硅基计划4.0 算法 归并排序
  • 关于发布未来工业互联网基础理论与关键技术重大研究计划2025年度项目指南的通告
  • RAG技术解析:AI如何“边查边答”,还要守住数据安全底线?
  • 多通道相参信号
  • 数据映射表
  • NVSpeech_170k 数据集音频提取处理
  • GC Root的一些理解
  • Windows 使用 SHFileOperation 实现文件复制功能
  • Linux防火墙-Firewalld
  • 面壁智能开源多模态大模型——MiniCPM-V 4.5本地部署教程:8B参数开启多模态“高刷”时代!