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
英文地址,請注明出處:http://en.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…