济南制作网站/网址查询服务器地址

济南制作网站,网址查询服务器地址,网站管理员容易做吗,外贸b2c哪个网站好目录 1. InetAddr类 类定义 代码说明 类实现 2.Socket类 类定义 类实现 3. Epoll类 类定义 构造与析构函数 方法实现 类实现 4. 使用模块化设计 示例使用(main.cpp) 5. 运行程序 随着程序复杂度的增加,单一的面向过程的代码会变得难以理…

目录

1. InetAddr类

类定义

代码说明 

类实现

2.Socket类

类定义

类实现

3. Epoll类

类定义

构造与析构函数

方法实现

类实现

4. 使用模块化设计

示例使用(main.cpp)

5. 运行程序


随着程序复杂度的增加,单一的面向过程的代码会变得难以理解和维护。为了提高代码的可读性和可维护性,我们可以通过模块化的方式,将程序分解为多个类,每个类负责特定的功能。这种设计不仅提高了代码的复用率,还能帮助开发者集中精力在每个单独的功能模块上,便于维护和扩展。

在本文中,我们将介绍一种简单的模块化设计方法,使用C++面向对象的特性,来设计一个网络编程框架。我们将创建三个关键类:InetAddrSocketEpoll。这些类的设计目的在于简化网络编程的过程,提高代码的可读性和可维护性。

1. InetAddr类

InetAddr类主要负责处理与IP地址相关的操作。它封装了sockaddr_in结构体,并提供了一系列方法来获取IP地址和端口。

类定义

#pragma once // 确保该头文件只被包含一次  #include <string>     // 引入字符串类  
#include <arpa/inet.h> // 提供网络地址结构定义及函数  
#include <stdio.h>    // 标准输入输出库  class InetAddr {
public:// 默认构造函数  InetAddr();// 带参数的构造函数,接受端口和可选的IP地址  InetAddr(unsigned short port, const char* ip = nullptr);// 获取sockaddr_in结构的指针,供外部使用  const sockaddr_in* getAddr() const { return &addr_; }// 设置sockaddr_in结构的地址,供外部使用  void setAddr(const struct sockaddr_in& addr) { addr_ = addr; }// 将地址转换为IP字符串格式  std::string toIp() const;// 将地址转换为IP:端口格式的字符串  std::string toIpPort() const;// 获取端口号  unsigned short toPort() const;private:struct sockaddr_in addr_; // 存储网络地址信息的结构体  
};

代码说明 

  • InetAddr 类用于处理网络地址信息,主要封装了 sockaddr_in 结构体,提供了获取和设置网络地址、IP转换等操作。
  • 构造函数
    • 默认构造函数:初始化为0的地址,设置地址族为IPv4。
    • 带参数的构造函数:允许用户指定端口和IP地址,并适当地初始化 sockaddr_in 结构体。
  • 公共方法
    • getAddr():返回存储的地址信息的常量引用,便于外部访问。
    • setAddr():允许设置或修改当前存储的 sockaddr_in 地址。
    • toIp():转换当前地址为点分十进制格式的字符串。
    • toIpPort():将IP和端口组合为字符串,便于显示。
    • toPort():获取当前对象的端口号,返回值为无符号短整型。

Socket类负责封装与套接字相关的操作,包括创建、绑定、监听和接受连接等。

类实现

#include "InetAddr.h"         // 包含InetAddr类的定义  
#include <string.h>           // 包含字符串操作函数  
#include <arpa/inet.h>       // 包含网络地址转换函数  // 默认构造函数  
InetAddr::InetAddr() {// 将地址结构清零,确保没有未定义的值  memset(&addr_, 0, sizeof(addr_));
}// 带参数的构造函数,用于初始化port和ip  
InetAddr::InetAddr(unsigned short port, const char* ip) {// 将地址结构清零  memset(&addr_, 0, sizeof(addr_));addr_.sin_family = AF_INET; // 设置地址族为IPv4  addr_.sin_port = htons(port); // 将主机字节序的端口转换为网络字节序  // 如果未提供IP,则使用INADDR_ANY,允许接受任何IP地址的连接  if (ip == nullptr) {addr_.sin_addr.s_addr = htonl(INADDR_ANY);}else {// 将字符串形式的IP地址转换为网络字节序的二进制格式  inet_pton(AF_INET, ip, &addr_.sin_addr.s_addr);}
}// 将存储的IP地址转换为字符串格式  
std::string InetAddr::toIp() const {char ip[64] = { 0 }; // 存储转换后的IP地址  // 将网络字节序的IP地址转换为字符串形式  inet_ntop(AF_INET, &addr_.sin_addr.s_addr, ip, sizeof(ip));return ip; // 返回IP字符串  
}// 将IP地址和端口组合为 "IP:port" 的格式  
std::string InetAddr::toIpPort() const {char buf[128] = { 0 }; // 存储组合后的字符串  // 使用sprintf将IP和端口格式化为字符串  sprintf(buf, "%s:%d", toIp().c_str(), toPort());return buf; // 返回组合后的字符串  
}// 获取存储的端口号  
unsigned short InetAddr::toPort() const {// 将网络字节序的端口转换为主机字节序并返回  return ntohs(addr_.sin_port);
}

2.Socket类

类定义

#pragma once // 确保该头文件只被包含一次  class InetAddr; // 前向声明InetAddr类  class Socket
{
public:// 默认构造函数,初始化Socket对象  Socket();// 带参数的构造函数,使用给定的文件描述符初始化Socket  Socket(int fd);// 析构函数,关闭Socket以释放资源  ~Socket();// 将Socket绑定到指定的InetAddr地址  void bind(InetAddr* serv_addr);// 接受来自客户端的连接,并返回新的套接字文件描述符  int accept(InetAddr* addr);// 将Socket设置为监听状态,准备接受连接  void listen();// 设置Socket为非阻塞模式  void setNonblock();// 获取套接字文件描述符  int fd() const { return sockfd_; }private:int sockfd_; // 存储套接字的文件描述符  
};
  • 构造函数

    • Socket(): 默认构造函数,用于创建一个新的TCP套接字。
    • Socket(int fd): 通过传入的文件描述符初始化套接字对象,允许外部使用现有套接字。
  • 成员函数

    • void bind(InetAddr* serv_addr): 绑定给定的地址信息到套接字。
    • void listen(): 设置套接字为监听状态,准备接收连接请求。
    • int accept(InetAddr* peerAddr): 接受客户端连接,并返回新连接的套接字文件描述符,此外可以获取客户端地址。
    • int fd() const: 返回当前套接字的文件描述符,供外部访问。
  • 私有成员变量

    • const int sockfd_: 存储套接字的文件描述符,使用 const 限制其在对象生命周期内不可更改。

类实现

#include "Socket.h"                // 引入Socket类的定义  
#include "util.h"          
#include "InetAddr.h"              // 引入InetAddr类的定义  
#include <fcntl.h>                 // 提供fcntl函数的定义  
#include <unistd.h>                // 提供close函数的定义  // 默认构造函数,创建一个TCP套接字  
Socket::Socket(): sockfd_(socket(AF_INET, SOCK_STREAM, 0)) // 创建一个IPv4 TCP套接字  
{// 检查套接字创建是否成功,如果失败、打印错误信息  perror_if(sockfd_ == -1, "socket");
}// 带参数的构造函数,通过给定的文件描述符初始化套接字  
Socket::Socket(int fd): sockfd_(fd) // 使用提供的文件描述符进行初始化  
{// 检查文件描述符是否有效  perror_if(sockfd_ == -1, "socket(int fd)");
}// 析构函数,关闭套接字以释放资源  
Socket::~Socket()
{if (sockfd_ != -1) { // 确保套接字有效  close(sockfd_); // 关闭套接字文件描述符  sockfd_ = -1;   // 将文件描述符标记为无效,防止重复关闭  }
}// 将套接字绑定到指定的InetAddr地址  
void Socket::bind(InetAddr* serv_addr)
{// 调用系统级绑定函数  int ret = ::bind(sockfd_, (sockaddr*)serv_addr->getAddr(), sizeof(sockaddr_in));// 检查绑定是否成功,如果失败,打印错误信息  perror_if(ret == -1, "bind");
}// 接受客户端连接,并返回新的套接字文件描述符  
int Socket::accept(InetAddr* addr)
{struct sockaddr_in cliaddr; // 存储客户端地址信息  socklen_t len = sizeof(cliaddr); // 存储地址长度  // 调用系统级接受函数  int cfd = ::accept(sockfd_, (struct sockaddr*)&cliaddr, &len);// 检查接受客户端连接是否成功,如果失败,打印错误信息  perror_if(cfd == -1, "accept");// 设置已连接客户端的地址信息  addr->setAddr(cliaddr);// 输出新连接的客户端信息  printf("new client fd %d ip: %s, port: %d connected..\n", cfd, addr->toIp().c_str(), addr->toPort());return cfd; // 返回新连接的套接字文件描述符  
}// 将套接字设置为监听状态,准备接受连接  
void Socket::listen()
{// 调用系统级监听函数,最多同时处理128个连接请求  int ret = ::listen(sockfd_, 128);// 检查监听是否成功,如果失败,打印错误信息  perror_if(ret == -1, "listen");
}// 将套接字设置为非阻塞模式  
void Socket::setNonblock()
{// 获取当前文件描述符的标志  int flag = fcntl(sockfd_, F_GETFL);flag |= O_NONBLOCK; // 将非阻塞标志添加到当前标志中  // 将新的标志设置回文件描述符  fcntl(sockfd_, F_SETFL, flag);
}

3. Epoll类

Epoll类用于处理epoll事件,包括创建epoll实例、管理文件描述符添加/删除以及等待事件的发生。

类定义

#pragma once // 确保该头文件只被包含一次  #include <sys/epoll.h> // 包含epoll相关的系统调用  
#include <vector>      // 引入vector标准库  
using std::vector;    // 使用std命名空间中的vector类  class Epoll
{
public:// 构造函数,初始化epoll实例  Epoll();// 析构函数,清理epoll资源  ~Epoll();// 更新给定文件描述符的事件  void update(int sockfd, int events, int op);// 从epoll中删除指定的文件描述符  void epoll_delete(int fd);// 等待事件发生,返回活跃的文件描述符事件  void Epoll_wait(vector<epoll_event>& active, int timeout = 10);private:int epfd_;                       // epoll实例的文件描述符  struct epoll_event* events_;      // 存储返回的事件  
};

构造与析构函数

  • 创建epoll实例并初始化事件数组。
  • 在析构函数中释放资源。

方法实现

  • update(): 添加、修改或删除文件描述符的事件。
  • wait(): 使用epoll_wait()等待活动事件并填充事件数组。

类实现

#include "Epoll.h"               // 引入Epoll类的定义  
#include "util.h"                // 引入自定义工具函数头文件  
#include <string.h>              // 引入cstring库以使用memset和相关函数  
#include <unistd.h>             // 引入unistd.h以使用close函数const int SIZE = 1024;         // 定义epoll事件数组的大小  // 构造函数,创建一个新的epoll实例并初始化事件数组  
Epoll::Epoll(): epfd_(epoll_create(1)), // 创建epoll实例,参数为1,表示初始的事件数  events_(new epoll_event[SIZE]) // 动态分配事件数组  
{// 检查epoll_create是否成功,失败则调用perror_if输出错误信息  perror_if(epfd_ == -1, "epoll_create");// 初始化事件数组,清空内存  memset(events_, 0, sizeof(epoll_event) * SIZE);
}// 析构函数,清理epoll资源  
Epoll::~Epoll()
{// 删除事件数组  delete[] events_; // 释放动态分配的事件数组  // 将epfd_设为-1以避免重复关闭  if (epfd_ != -1) {close(epfd_); // 关闭epoll实例的文件描述符  epfd_ = -1; // 将文件描述符设置为-1表示无效  }
}// 更新给定的文件描述符,设置其事件类型  
void Epoll::update(int sockfd, int events, int op)
{struct epoll_event ev; // 创建epoll_event结构体以存储事件信息  memset(&ev, 0, sizeof(ev)); // 清空结构体  ev.data.fd = sockfd; // 将文件描述符存储在event结构体中  ev.events = events; // 设置感兴趣的事件  // 调用epoll_ctl更新epoll实例  int ret = epoll_ctl(epfd_, op, sockfd, &ev);// 检查epoll_ctl是否成功  perror_if(ret == -1, "epoll_ctl");
}// 从epoll中删除指定的文件描述符  
void Epoll::epoll_delete(int fd)
{// 调用epoll_ctl删除指定的文件描述符  int ret = epoll_ctl(epfd_, EPOLL_CTL_DEL, fd, nullptr);// 检查epoll_ctl是否成功  perror_if(ret == -1, "epoll_ctl del");
}// 等待事件发生,返回活跃的事件列表  
void Epoll::Epoll_wait(vector<epoll_event>& active, int timeout)
{// 调用epoll_wait等待事件的发生  int nums = epoll_wait(epfd_, events_, SIZE, timeout);// 检查epoll_wait是否成功  perror_if(nums == -1, "epoll_wait");// 将活跃的事件添加到active vector中  for (int i = 0; i < nums; ++i) {active.emplace_back(events_[i]); // 将每个活跃事件存入active数组  }
}

4. 使用模块化设计

通过将网络相关的功能分割成几个类,可以简化主要的服务器逻辑。使用这些类,我们可以方便地进行网络编程而不必关注底层的细节。

示例使用(main.cpp)

下面是如何使用这些类来构建一个简单的服务器:

#include "Epoll.h"        // 引入Epoll类的定义  
#include "Socket.h"      // 引入Socket类的定义  
#include "util.h"          // 引入工具函数的头文件  
#include "InetAddr.h"       // 引入InetAddr类的定义  
#include <stdio.h>              // 引入标准输入输出库  
#include <string.h>             // 引入cstring库以使用memset和相关函数  
#include <unistd.h>             // 引入unistd库以使用read和close函数  const int READ_BUFFER = 1024;  // 定义读取缓冲区的大小  
const int MAXSIZE = 1024;      // 定义最大连接数(未使用)  // 前向声明函数,用于处理事件  
void handleEvent(int sockfd, Epoll& poll);int main()
{Socket serv_socket;             // 创建一个服务器套接字  InetAddr saddr(10000);         // 创建一个InetAddr对象,用于绑定到端口10000  serv_socket.bind(&saddr);       // 绑定服务器套接字到指定地址  serv_socket.listen();           // 开始监听客户端连接  serv_socket.setNonblock();      // 设置服务器套接字为非阻塞模式  Epoll poll;                     // 创建epoll实例  poll.update(serv_socket.fd(), EPOLLIN, EPOLL_CTL_ADD); // 将服务器套接字添加到epoll实例中,监控可读事件  // 主循环,持续处理事件  while (1){vector<epoll_event> active; // 存储活动事件的向量  poll.Epoll_wait(active);     // 等待事件的发生  int nums = active.size();    // 当前活动事件的数量  for (int i = 0; i < nums; ++i) {int curfd = active[i].data.fd; // 获取当前事件对应的文件描述符  // 检查是否是可读事件  if (active[i].events & EPOLLIN) {if (curfd == serv_socket.fd()) { // 如果当前文件描述符是服务器套接字  InetAddr caddr;              // 创建一个InetAddr对象,存储客户端地址  Socket* cli_socket = new Socket(serv_socket.accept(&caddr)); // 接受客户端连接并创建新的套接字  // 注意:需要处理内存泄漏(后续版本将修复内存管理)  cli_socket->setNonblock();   // 设置客户端套接字为非阻塞模式  poll.update(cli_socket->fd(), EPOLLIN, EPOLL_CTL_ADD); // 将客户端套接字添加到epoll实例  }else {handleEvent(curfd, poll);   // 处理其他可读事件  }}else if (active[i].events & EPOLLOUT) {// 其他事件以后的版本会实现  }}}return 0; // 主程序结束  
}// 处理可读事件的函数  
void handleEvent(int sockfd, Epoll& poll) {char buf[READ_BUFFER];         // 声明读取缓冲区  memset(buf, 0, sizeof(buf));   // 清空缓冲区  // 从套接字读取数据  ssize_t bytes_read = read(sockfd, buf, sizeof(buf));// 判断读取结果  if (bytes_read > 0) {// 成功读取数据,输出客户端发来的消息  printf("client fd %d says: %s\n", sockfd, buf);// 将接收到的数据写回给客户端(回显)  write(sockfd, buf, bytes_read);}else if (bytes_read == -1) { // 读取出错  perror_if(1, "read");    // 调用错误处理函数  }else if (bytes_read == 0) {  // 客户端断开连接  printf("client fd %d disconnected\n", sockfd);poll.epoll_delete(sockfd); // 从epoll实例中删除该套接字  close(sockfd);             // 关闭套接字  }
}

5. 运行程序

g++ -o Server main.cpp Epoll.cpp util.cpp Socket.cpp InetAddr.cpp

编译完成后,可以通过以下命令运行服务器:

./Server        # 启动服务器

客户端可以使用之前的客户端程序作为连接方式,确保与服务器在同一网络下运行。

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

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

相关文章

视频生成的测试时Scaling时刻!清华开源Video-T1,无需重新训练让性能飙升

来源 | 机器之心 视频作为包含大量时空信息和语义的媒介&#xff0c;对于 AI 理解、模拟现实世界至关重要。视频生成作为生成式 AI 的一个重要方向&#xff0c;其性能目前主要通过增大基础模型的参数量和预训练数据实现提升&#xff0c;更大的模型是更好表现的基础&#xff0c…

【强化学习】基于深度强化学习的微能源网能量管理与优化策略研究【Python】

目录 主要内容 程序要点 2.1 微能源网系统组成 2.2 强化学习及Q学习算法 部分代码 运行结果 下载链接 主要内容 该程序借助深度 Q 网络&#xff08;DQN&#xff09;&#xff0c;学习预测负荷、风 / 光可再生能源功率输出及分时电价等环境信息&#xff0c;运用…

dom0-kernel: /thermal-zones/soc_max/cooling-maps/map0: could not find phandle 2

问题描述&#xff1a; 由于soc_max下某个节点找不到&#xff0c;到时dom0-kernel后面有很多有关thermal热管理之类报错 问题解决及其原因分析&#xff1a; 这是因为在Xen解析相关节点时&#xff0c;soc_max下的某个节点被跳过了&#xff0c;注释掉相关的cpu节点处理dom0就可以找…

专注自习室:番茄工作法实践

专注自习室&#xff1a;番茄工作法实践 我需要一个任务管理工具&#xff0c;但在网上找了很多都找不到合适的工具。市面上的大多数产品过于强调任务完成性&#xff0c;给我带来了很强的心理压力&#xff0c;这种压力最终反而降低了我的工作效率。于是我决定自己动手&#xff0…

VUE3项目VITE打包优化

VUE3项目VITE打包优化 代码加密依赖配置效果对比图 自动导入依赖配置 代码压缩依赖配置效果对比图 图片压缩依赖配置效果对比图 字体压缩总结与实践运用效果 代码加密 依赖 npm install -D vite-plugin-bundle-obfuscator配置 import vitePluginBundleObfuscator from "…

机器学习——LightGBM

LightGBM(light gradient boosting machine&#xff0c;轻量梯度提升机)是对XGBoost进行改进的模型版本&#xff0c;其三者之间的演变关系为&#xff1a;GBDT-》XGBoost-》LightGBM&#xff0c;依次对性能进行优化&#xff0c;尽管XGBoost已经很高效了&#xff0c;但是仍然有缺…

内网服务器无法通过公网地址访问映射到公网的内网服务

内网服务器无法通过公网地址访问映射到公网的内网服务 问题现象问题原因解决方法总结 前几天遇到一个网络问题&#xff0c;在这里做下记录&#xff0c;希望能帮助到有相同问题的朋友。 问题现象 网络拓扑如上所示&#xff0c;服务器1和服务器2在同一内网&#xff0c;网段均为1…

python每日十题(13)

一般把计算机完成一条指令所花费的时间称为一个指令周期。指令周期越短&#xff0c;指令执行就越快。本题答案为D选项。 顺序程序具有顺序性、封闭性和可再现性的特点&#xff0c;使得程序设计者能够控制程序执行的过程(包括执行顺序、执行时间&#xff09;&#xff0c;对程序执…

多智能体功能分化的核心优势是什么:提升效率,查漏补缺

多智能体功能分化的核心优势是什么:提升效率,查漏补缺 在于通过分工协作提升整体效率、灵活性和鲁棒性。 1. 提升效率与专业性 原理:单一智能体无需处理全流程,通过专业化分工减少冗余计算和决策延迟。 示例: 自动驾驶系统: 感知智能体:专门处理摄像头、激光雷达等传…

COMPASS:通过残差强化学习和技能合成实现跨具身移动策略

25年2月来自 Nvidia、UC Berkeley 和 UT Austin 的论文“COMPASS: Cross-embOdiment Mobility Policy via ResiduAl RL and Skill Synthesis”。 随着机器人越来越多地部署在不同的应用领域&#xff0c;可泛化的跨具身移动策略变得越来越重要。虽然经典的移动栈已被证明在特定…

无人机,雷达定点飞行时,位置发散,位置很飘,原因分析

参考&#xff1a; 无人车传感器 IMU与GPS数据融合进行定位机制_gps imu 组合定位原始数-CSDN博客 我的无人机使用雷达定位&#xff0c;位置模式很飘 雷达的更新频率也是10HZ&#xff0c; 而px飞控的频率是100HZ&#xff0c;没有对两者之间的频率差异做出处理 所以才导致无人…

学习threejs,使用Sprite精灵、SpriteMaterial精灵材质

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.Sprite1.1.1 ☘️代码…

外星人入侵(python设计小游戏)

这个游戏简而言之就是操作一个飞机对前方的飞船进行射击&#xff0c;和一款很久之前的游戏很像&#xff0c;这里是超级低配版那个游戏&#xff0c;先来看看效果图&#xff1a; 由于设计的是全屏的&#xff0c;所以电脑不能截图。。。。 下面的就是你操控的飞船&#xff0c;上面…

23种设计模式-备忘录(Memento)设计模式

备忘录设计模式 &#x1f6a9;什么是备忘录设计模式&#xff1f;&#x1f6a9;备忘录设计模式的特点&#x1f6a9;备忘录设计模式的结构&#x1f6a9;备忘录设计模式的优缺点&#x1f6a9;备忘录设计模式的Java实现&#x1f6a9;代码总结&#x1f6a9;总结 &#x1f6a9;什么是…

某鱼、某宝 sign 签名算法分析记录

【作者主页】&#xff1a;小鱼神1024 【知识星球】&#xff1a;小鱼神的逆向编程圈 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 本文章中所有内容仅供学习交流使用&#xff0c;不用于其…

【C语言】分支与循环(上)

前言&#xff1a;C语言是由顺序结构、选择结构、循环结构组成的结构化的程序设计语言。 那C语言是如何设计和实现这些结构的呢&#xff1f;话不多说&#xff0c;马上开始。 三种结构如图所示&#xff1a; 我们可以使用 if else语句、 switch语句 来实现选择&#xff08;分支&am…

Springboot学习笔记3.20

目录 1.实战篇第一课 我们将会在本次实战中学习到哪些知识点&#xff1f; 开发模式和环境搭建&#xff1a; 注册接口 1.Lombok 2.开发流程 1.controller层&#xff0c;这个层会指明访问路径和要执行的逻辑&#xff1a; 2.我们把返回结果根据接口文档包装成一个类result&a…

全新升级 | Built For You Spring ‘25 发布,Fin 智能客服实现新突破!

图像识别、语音交互、任务自动化&#xff0c;立即体验智能客服蜕变&#xff01; 上周&#xff0c;Intercom 举办了 Built For You Spring 25 发布会&#xff0c;正式揭晓了 AI Agent Fin 的一系列令人振奋的更新。Fin 正在以前所未有的速度革新客户支持模式——它已经成功解决了…

需求导向的K8S网络原理分析:Kube-proxy、Flannel、Calico的地位和作用

最近发现自己似乎从来没学明白过Kubernetes网络通信方案&#xff0c;特开一贴复习总结一下。 在k8s中&#xff0c;每个 Pod 都拥有一个独立的 IP 地址&#xff0c;而且假定所有 Pod 都在一个可以直接连通的、扁平的网络空间中。所以不管它们是否允许在同一个 Node&#xff08;宿…

Vulnhub:Digitalword.local: FALL靶机渗透

将靶机按照图中连接方式打开&#xff0c;fall在virtualBox中打开 信息收集 扫描得ip arp-scan -l 扫描端口 nmap -A -T4 -sV -p- 扫描目录 gobuster dir -u http://192.168.117.160 -x php,txt,html -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 一个一个…