【boost网络库从青铜到王者】第二篇:asio网络编程中的socket的监听和连接

文章目录

  • 1、网络编程基本流程
  • 2、终端节点endpoint的创建
      • 2.1、客户端终端节点endpoint的创建
      • 2.2、服务器终端节点endpoint的创建
  • 3、服务器与客户端通信套接字socket的创建
  • 4、服务器监听套接字socket的创建
  • 5、绑定accpet监听套接字
  • 6、客户端连接指定的端点
  • 7、服务器接收连接
  • 8、ipv6协议和ipv4协议区别
  • 9、0.0.0.0地址和127.0.0.1地址区别

1、网络编程基本流程

网络编程的基本流程对于服务端是这样:

  • 服务器:

    • socket——创建socket对象。

    • bind——绑定本机ip+port

    • listen——监听来电,若在监听到来电,则建立起连接。

    • accept——再创建一个socket对象给其收发消息。原因是现实中服务端都是面对多个客户端,那么为了区分各个客户端,则每个客户端都需再分配一个socket对象进行收发消息。

    • readwrite——就是收发消息了。消息就是协议,这里通过protobuf来解析。

  • 客户端

    • socket——创建socket对象。

    • connect——根据服务端ip+port,发起连接请求。

    • write、read——建立连接后,就可发收消息了。

图文如下:
在这里插入图片描述
接下来按照上述流程,我们用boost::asio逐步介绍。

2、终端节点endpoint的创建

2.1、客户端终端节点endpoint的创建

所谓终端节点就是用来通信的端对端的节点,可以通过ip地址和端口构造,其的节点可以连接这个终端节点做通信。

如果我们是客户端,我们可以通过对端的ip端口构造一个endpoint,用这个endpoint和其通信。

#include"asio_demo.h"

int32_t BoostAsio::ClientEndPoint(std::string& raw_ip_address) {

	//step1:Assume that the client application has already 
	// obtained the IP-address and the protocol port number.
	
	//std::string raw_ip_address = "127.0.0.1";
	uint16_t port_num = 9273;

	// Used to store information about error that happens
	// while parsing the raw IP-address.
	boost::system::error_code ec;

	//Step 2. Using IP protocol version independent address
	// representation.
	boost::asio::ip::address ip_address = boost::asio::ip::address::from_string(raw_ip_address, ec);
	if (0 != ec.value()) {
		std::cout << "Failed to parse the Ip Adress,error_code = " << ec.value() << " . Message: " << ec.message();
		return ec.value();
	}

	// Step 3.
	boost::asio::ip::tcp::endpoint ep(ip_address, port_num);

	// Step 4. The endpoint is ready and can be used to specify a 
	// particular server in the network the client wants to 
	// communicate with.
}

这段代码是一个使用 Boost.Asio 库创建 TCP 客户端端点的示例。以下是代码中每个步骤的解释:

  • 包含语句: 代码包含了 “asio_demo.h” 头文件。这个头文件可能包含了 Boost.Asio 库的声明和必要的包含。

  • ClientEndPoint 函数: 这个函数用于使用 Boost.Asio 创建 TCP 客户端端点。这个函数用于使用 Boost.Asio 创建 TCP 客户端端点,并接受一个 IP 地址字符串作为输入参数。

  • 步骤 1: 客户端应用程序假设已经获取了原始 IP 地址(在本例中是 “127.0.0.1”)和端口号(9273),以便与服务器通信。

  • 步骤 2Boost.Asio 提供了从字符串表示转换为 IP 地址的方法。在这里,它使用 boost::asio::ip::address::from_string 函数将原始 IP 地址字符串转换为 ip::address 对象。error_code 参数用于检查在解析过程中是否发生了错误。

  • 步骤 3boost::asio::ip::tcp::endpoint 类表示一个端点(IP 地址和端口号),可以用于指定网络中的特定服务器。使用解析后的 IP 地址和端口号创建了 ep 对象。

  • 步骤 4: 此时,ep 对象表示客户端端点,可以用于连接指定的服务器上的 TCP。然而,代码并没有显示实际连接过程或与服务器的任何通信,因此它只是为将来使用而准备端点。

请注意,这段代码似乎是更大程序的一部分,所提供的片段并没有显示客户端实际如何与服务器交互或执行网络通信。Boost.Asio 库通常用于在 C++ 中进行异步网络编程,允许开发人员创建高效和可扩展的网络应用程序。

2.2、服务器终端节点endpoint的创建

如果是服务端,则只需根据本地地址绑定就可以生成endpoint

int32_t BoostAsio::ServerEndPoint(uint16_t& port_num) {
	// Step 1. Here we assume that the server application has
	//already obtained the protocol port number.

	//uint16_t port_num = 9273;

	// Step 2. Create special object of asio::ip::address class
	// that specifies all IP-addresses available on the host. Note
	// that here we assume that server works over IPv6 protocol.

	boost::asio::ip::address ip_address = boost::asio::ip::address_v6::any();

	//Step 3.
	boost::asio::ip::tcp::endpoint ep(ip_address, port_num);

	// Step 4. The endpoint is created and can be used to 
   // specify the IP addresses and a port number on which 
   // the server application wants to listen for incoming 
   // connections.

	return 0;
}

这段代码是一个使用 Boost.Asio 库创建 TCP 服务器端点的示例。以下是代码中每个步骤的解释:

  • ServerEndPoint 函数: 这个函数用于使用 Boost.Asio 创建 TCP 服务器端点,并且传入一个端口号作为参数。

  • 步骤 1: 服务器应用程序已经获得了一个协议端口号,并将这个端口号作为参数传递给函数。

  • 步骤 2: 使用 Boost.Asioip::address_v6::any() 函数创建了一个特殊的 ip::address 对象,表示服务器将监听主机上的所有可用 IPv6 地址。这意味着服务器将监听所有可用的网络接口。

  • 步骤 3: 使用步骤 2 中创建的 IP 地址和传入的端口号,创建了一个 boost::asio::ip::tcp::endpoint 对象 ep,表示服务器端点。

  • 步骤 4: 此时,ep 对象表示一个可以用于监听传入连接请求的 TCP 端点,其 IP 地址为所有可用的 IPv6 地址,而端口号由函数参数 port_num 决定。

最后,函数返回一个值,这里是 0,表示函数执行成功。

总之,这段代码允许你通过传入一个端口号来创建一个服务器端点,然后服务器可以用这个端点在特定的 IP 地址和端口上监听传入的连接请求。

3、服务器与客户端通信套接字socket的创建

服务器和客户端所用的通信的socket都是一样的。创建socket分为4步:

  • 创建上下文io_context
  • 选择协议。
  • 生成通信socket
  • 打开通信socket
int32_t BoostAsio::CreateTcpSocket() {
	// Step 1. An instance of 'io_service' class is required by
	// socket constructor. 
	boost::asio::io_context context;	

	// Step 2. Creating an object of 'tcp' class representing
	// a TCP protocol with IPv4 as underlying protocol.
	boost::asio::ip::tcp protocol = boost::asio::ip::tcp::v4();

	// Step 3. Instantiating an active TCP socket object.
	boost::asio::ip::tcp::socket sock(context);

	// Used to store information about error that happens
	// while opening the socket.
	boost::system::error_code ec;

	// Step 4. Opening the socket.
	sock.open(protocol, ec);
	if (0 != ec.value()) {
		//Failed to open the socket
		std::cout << "Failed to open the socket,error_code = " << ec.value() << ". Message: " << ec.message();
		return ec.value();
	}

	return 0;
}

这段代码是使用 Boost.Asio 库创建一个 TCP 套接字的过程,让我们逐步解释:

  • io_context 创建: 首先,通过创建 boost::asio::io_context 类的实例 context,用于管理异步 I/O 操作。

  • 协议选择: 选择使用 IPv4 的 TCP 协议,这里使用 boost::asio::ip::tcp::v4() 创建 tcp 对象来表示。

  • 创建套接字: 创建了一个 boost::asio::ip::tcp::socket 对象 sock,它代表一个 TCP 套接字。

  • 错误处理对象: 创建一个 boost::system::error_code 对象 ec,用于存储可能在打开套接字时发生的错误信息。

  • 打开套接字: 使用 sock.open(protocol, ec) 打开套接字。如果套接字打开过程中发生错误,会将错误码存储在 ec 中,然后检查 ec 是否非零,如果非零则表示打开套接字失败,输出错误信息。

  • 返回结果: 最后返回一个整数值,表示操作的结果。如果返回值为 0,表示套接字创建并打开成功。

这段代码演示了如何使用 Boost.Asio 库来创建并打开一个 TCP 套接字,并在过程中处理错误情况。这对于进行网络通信的程序非常有用,因为可以通过异步操作来管理网络连接和数据传输。

4、服务器监听套接字socket的创建

服务端,我们还需要生成一个acceptorsocket,用来监听接收新来自客户端的连接。

  • 创建上下文iocontext
  • 选择协议
  • 生成监听socket
  • 打开监听socket
int32_t BoostAsio::CreateAcceptSocket() {
	// Step 1. An instance of 'io_service' class is required by
	// socket constructor. 
	boost::asio::io_context context;

	// Step 2. Creating an object of 'tcp' class representing
    // a TCP protocol with IPv6 as underlying protocol.

	boost::asio::ip::tcp protocol = boost::asio::ip::tcp::v6();

	// Step 3. Instantiating an acceptor socket object.
	boost::asio::ip::tcp::acceptor accept(context);

	// Used to store information about error that happens
	// while opening the acceptor socket.
	boost::system::error_code ec;

	// Step 4. Opening the acceptor socket.
	accept.open(protocol, ec);
	if (0 != ec.value()) {
		std::cout << "Failed to open the accept socket!" << " Error code = " << ec.value() << " . Message: " << ec.message();
		return ec.value();
	}

	return 0;
}

这段代码是使用 Boost.Asio 库创建一个监听套接字**(acceptor socket)**的过程,让我们逐步解释:

  • io_context 创建: 通过创建 boost::asio::io_context 类的实例 context,用于管理异步 I/O 操作。

  • 协议选择: 选择使用 IPv6TCP 协议,这里使用 boost::asio::ip::tcp::v6() 创建 tcp 对象来表示。

  • 创建接收套接字: 创建了一个 boost::asio::ip::tcp::acceptor 对象 accept它代表一个接收来自客户端连接监听套接字。

  • 错误处理对象: 创建一个 boost::system::error_code 对象 ec,用于存储可能在打开监听套接字时发生的错误信息。

  • 打开接收套接字: 使用 accept.open(protocol, ec) 打开监听套接字。如果在打开过程中发生错误,会将错误码存储在 ec 中,然后检查 ec 是否非零,如果非零则表示打开监听套接字失败,输出错误信息。

  • 返回结果: 最后返回一个整数值,表示操作的结果。如果返回值为 0,表示监听套接字创建并打开成功。

这段代码演示了如何使用 Boost.Asio 库来创建并打开一个监听套接字,用于接受传入的连接请求。监听套接字通常用于服务器端,用于等待客户端的连接。

5、绑定accpet监听套接字

对于accept类型的socket,服务器要将其绑定到指定的断点,所有连接这个端点的连接都可以被接收到。

int32_t BoostAsio::BindAcceptSocket(uint16_t& port_num) {
	// Step 1. Here we assume that the server application has
	// already obtained the protocol port number.

	// Step 2. Creating an endpoint.
	boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address_v4::any(), port_num);

	// Used by 'accept' class constructor.
	boost::asio::io_context context;

	// Step 3. Creating and opening an acceptor socket.
	boost::asio::ip::tcp::acceptor accept(context, ep.protocol());

	boost::system::error_code ec;

	// Step 4. Binding the acceptor socket.
	accept.bind(ep, ec);

	// Handling errors if any.
	if (0 != ec.value()) {
		std::cout << "Failed to bind the accept socket!" << "Error code : " << ec.value() << ". Message:" << ec.message();
		return ec.value();
	}
	return 0;
}

这段代码演示了使用 Boost.Asio 库创建创建并绑定一个监听套接字 (acceptor socket) 的过程,让服务器可以监听指定端口号上的连接请求。下面是代码的解释:

  • 创建端点: 通过创建 boost::asio::ip::tcp::endpoint 对象 ep,指定了一个 IP 地址为 boost::asio::ip::address_v4::any(),表示监听所有可用的 IPv4 地址。port_num 则是提前获取到的端口号。

  • io_context 创建: 创建了 boost::asio::io_context 类的实例 context,用于管理异步 I/O 操作。

  • 创建和打开监听套接字: 使用 boost::asio::ip::tcp::acceptor 对象的构造函数创建了一个监听套接字 accept,并指定了 ep.protocol()(即 IPv4)。

  • 错误处理对象: 创建一个 boost::system::error_code 对象 ec,用于存储可能在绑定监听套接字时发生的错误信息。

  • 绑定监听套接字: 使用 accept.bind(ep, ec) 绑定监听套接字到指定的 IP 地址和端口。如果在绑定过程中发生错误,会将错误码存储在 ec 中,然后检查 ec 是否非零,如果非零则表示绑定监听套接字失败,输出错误信息。

  • 返回结果: 最后返回一个整数值,表示操作的结果。如果返回值为 0,表示监听套接字绑定成功。

这段代码展示了如何使用 Boost.Asio 库创建一个绑定到指定 IP 地址和端口的监听套接字,用于等待客户端的连接请求。

6、客户端连接指定的端点

作为客户端可以连接服务器指定的端点**(ip+端口)**进行连接。

int32_t BoostAsio::ClientConnectServer(std::string& raw_ip_address, uint16_t& port_num) {
	// Step 1. Assume that the client application has already
	// obtained the IP address and protocol port number of the
	// target server.

	try {
		// Step 2. Creating an endpoint designating 
		// a target server application.
		boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string(raw_ip_address), port_num);

		boost::asio::io_context context;

		// Step 3. Creating and opening a socket.
		boost::asio::ip::tcp::socket socket(context, ep.protocol());

		// Step 4. Connecting a socket.
		socket.connect(ep);

		// At this point socket 'sock' is connected to 
	   // the server application and can be used
	   // to send data to or receive data from it.

	}
	// Overloads of asio::ip::address::from_string() and 
	 // asio::ip::tcp::socket::connect() used here throw
	// exceptions in case of error condition.
	catch (boost::system::system_error& e) {
		std::cout << "Error occured! Error code = " << e.code() << " .Message:" << e.what();
		return e.code().value();
	}
	return 0;
}

这段代码实现了一个客户端连接服务器的过程。下面是代码的解释:

  • 创建端点: 通过使用 boost::asio::ip::address::from_string(raw_ip_address) 将提供的 IP 地址字符串解析为 IP 地址对象,并使用 port_num 作为端口号,创建了一个 boost::asio::ip::tcp::endpoint 对象 ep,该对象指定了要连接的服务器的终端。

  • io_context 创建: 创建了 boost::asio::io_context 类的实例 context,用于管理异步 I/O 操作。

  • 创建和打开套接字: 使用 boost::asio::ip::tcp::socket 对象的构造函数创建了一个客户端套接字 socket,并指定了 ep.protocol(),即服务器的协议类型。

  • 连接套接字: 使用 socket.connect(ep) 方法来连接服务器。这一步骤将客户端的套接字与服务器的套接字建立连接,从此客户端可以通过该套接字与服务器进行通信。

  • 错误处理: 使用 try-catch 语句来捕获可能发生的异常。如果连接过程中发生错误,会抛出 boost::system::system_error 异常。在 catch 块中,会输出错误信息,包括错误码和错误消息。

  • 返回结果: 最后返回一个整数值,表示操作的结果。如果返回值为 0,表示连接成功。

这段代码用于在客户端创建套接字并连接到服务器,以便与服务器进行数据交换。

7、服务器接收连接

当有客户端连接时,服务器需要接收连接:

int32_t ServerAcceptClientConnect(uint16_t& port_num) {
	// The size of the queue containing the pending connection
	// requests.
	//连接队列
	const int BACKLOG_SIZE = 30;

	// Step 1. Here we assume that the server application has
	// already obtained the protocol port number.

	// Step 2. Creating a server endpoint.
	boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address_v4::any(), port_num);

	boost::asio::io_context context;

	try {
		// Step 3. Instantiating and opening an acceptor socket.
		boost::asio::ip::tcp::acceptor accept(context, ep.protocol());

		// Step 4. Binding the acceptor socket to the 
		// server endpint.
		accept.bind(ep);

		// Step 5. Starting to listen for incoming connection
		// requests.
		accept.listen(BACKLOG_SIZE);

		// Step 6. Creating an active socket.
		boost::asio::ip::tcp::socket socket(context);

		// Step 7. Processing the next connection request and 
		// connecting the active socket to the client.
		accept.accept(socket);

		// At this point 'sock' socket is connected to 
		//the client application and can be used to send data to
		// or receive data from it.
	}
	catch (boost::system::system_error& e) {
		std::cout << "Error occured! Error code = " << e.code() << ". Message: " << e.what();
		return e.code().value();
	}
	return 0;
}

这段代码实现了服务器接受客户端连接的过程。以下是代码的解释:

  • 连接队列大小: 定义了连接队列中待处理的连接请求的最大数量,通过 const int BACKLOG_SIZE = 30; 定义。

  • 创建服务器端点: 使用 boost::asio::ip::tcp::endpoint 对象创建一个服务器端点对象 ep,使用 boost::asio::ip::address_v4::any() 表示服务器可以绑定到任何可用的 IPv4 地址,同时使用提供的 port_num 作为端口号。

  • io_context 创建: 创建了 boost::asio::io_context 类的实例 context,用于管理异步 I/O 操作。

  • 实例化和打开接受套接字: 使用 boost::asio::ip::tcp::acceptor 构造函数创建一个接受套接字 accept,并指定协议类型。

  • 绑定接受套接字: 使用 accept.bind(ep) 方法将接受套接字绑定到服务器端点。

  • 开始监听连接请求: 使用 accept.listen(BACKLOG_SIZE) 方法开始监听传入的连接请求,并指定连接队列的大小

  • 创建活动套接字并处理连接请求: 创建一个活动套接字 socket,并使用 accept.accept(socket) 方法来处理下一个连接请求,并将活动套接字与客户端连接,进行协议传输。

  • 错误处理: 使用 try-catch 语句来捕获可能发生的异常。如果发生错误,会抛出 boost::system::system_error 异常。在 catch 块中,会输出错误信息,包括错误码和错误消息。

  • 返回结果: 最后返回一个整数值,表示操作的结果。如果返回值为 0,表示连接成功。

这段代码用于在服务器端创建接受套接字,绑定端点并开始监听连接请求,然后处理下一个连接请求并与客户端建立连接,以便进行数据交换。

8、ipv6协议和ipv4协议区别

IPv4(Internet Protocol version 4)IPv6(Internet Protocol version 6) 是互联网通信中使用的两种不同版本的IP协议,它们有以下主要区别:

  • 地址长度:

    • IPv4使用32位二进制地址,通常以点分十进制表示(例如:192.168.1.1)。
    • IPv6使用128位二进制地址,通常以冒号分隔的十六进制表示(例如:2001:0db8:85a3:0000:0000:8a2e:0370:7334)。
  • 地址数量:

    • IPv4提供了大约42亿个唯一地址,但随着互联网的发展,IPv4地址耗尽成为了问题,需要使用NAT等技术来实现地址复用。
    • IPv6提供了远远超过IPv4的地址数量,理论上可以支持约340十万亿亿亿亿个唯一地址,因此可以解决IPv4地址耗尽问题。
  • 地址表示:

    • IPv4地址以32位二进制表示,使用四个8位字节表示,每个字节使用十进制表示。
    • IPv6地址以128位二进制表示,使用八个16位字节表示,每个字节使用十六进制表示。
  • 地址类型:

    • IPv4的地址分为公有地址(用于公共互联网)和私有地址(用于局域网内部)。
    • IPv6的地址一般都是全球唯一的,不再使用私有地址的概念,因为地址数量足够满足所有需求。
  • 协议特性:

    • IPv6引入了一些新的特性,如移动IPv6支持、自动地址配置、IPSec等,以提升网络的效率、安全性和功能。
  • 包头大小:

    • IPv6包头相对于IPv4包头有一些增加,主要是因为引入了更多的特性,但这也使得IPv6的路由和分片等操作更加高效。
  • 部署和过渡:

    • 由于IPv4已经被广泛使用,IPv6的过渡是逐步进行的,许多网络同时支持IPv4IPv6,以保障兼容性。
    • 一些服务提供商、网站和设备已经开始支持IPv6,但完全的IPv6广泛部署仍在进行中。

总体来说,IPv6是为了解决IPv4地址耗尽问题而设计的,它提供了更大的地址空间和更多的功能,逐渐在全球范围内推广和部署。

9、0.0.0.0地址和127.0.0.1地址区别

  • 0.0.0.0地址:

    • 0.0.0.0: 这个 IP 地址表示“所有可用的 IP 地址”或“任何主机”。当一个服务器监听在这个 IP 地址上,它将能够接受来自网络上所有可用 IP 地址的连接。这在服务器需要在多个网络接口上监听时很有用,因为它能够接受来自所有接口的连接请求。这通常用于公共服务器,如 Web 服务器,以便能够处理来自不同来源的连接。
  • 127.0.0.1:

    • 127.0.0.1: 这是称为“回环地址”的特殊 IP 地址。它是本地主机上的回环接口,也就是说,它指向自己。当一个程序连接到 127.0.0.1 地址时,它实际上连接到本地计算机上的自身,这对于测试网络通信或本地服务非常有用。因此,127.0.0.1 被称为“本地回环地址”或“本地主机”。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网工最常犯的9大错误,越早知道越吃香

下午好&#xff0c;我的网工朋友 我们常说&#xff0c;人要学会避免错误&#xff0c;尤其是对在职场生活的打工人来说&#xff0c;更是如此。 学生时代&#xff0c;我们通过错题本收集错误&#xff0c;提高刷题正确率和分数&#xff0c;但到了职场&#xff0c;因为没有量化的…

WebAPIs 第四天

1.日期对象 2.节点操作 3.M端事件 4.JS插件 一.日期对象 实例化时间对象方法时间戳 日期对象&#xff1a;用来表示时间的对象 作用&#xff1a;可以得到当前系统时间 1.1 实例化 ① 概念&#xff1a;在代码中发现了new关键字时&#xff0c;一般将这个操作称为实例化 …

九、多态(2)

本章概要 构造器和多态 构造器调用顺序继承和清理构造器内部多态方法的行为 协变返回类型使用继承设计 替代 vs 扩展向下转型与运行时类型信息 构造器和多态 通常&#xff0c;构造器不同于其他类型的方法。在涉及多态时也是如此。尽管构造器不具有多态性&#xff08;事实上…

DoIP学习笔记系列:(五)“安全认证”的.dll从何而来?

文章目录 1. “安全认证”的.dll从何而来?1.1 .dll文件base1.2 增加客户需求算法传送门 DoIP学习笔记系列:导航篇 1. “安全认证”的.dll从何而来? 无论是用CANoe还是VFlash,亦或是编辑cdd文件,都需要加载一个与$27服务相关的.dll(Windows的动态库文件),这个文件是从哪…

vscode配置vue用户代码片段

打开vscode软件 选中左下角的设置按钮&#xff0c;再点击用户代码片段&#xff08;如图&#xff09; 再选择vue.json文件/新建全局代码片段&#xff08;如图&#xff09; 进行相关配置&#xff08;如下代码&#xff09; {"Vue2 quickly build template": {&q…

Unity UI.Image 六边形+流光 Shader

效果图 参考代码 Shader"Custom/HexFlowImage" {Properties{[PerRendererData] _MainTex ("Sprite Texture", 2D) "white" {}_Color ("Tint", Color) (1,1,1,1)_StencilComp ("Stencil Comparison", Float) 8_Stencil (…

SQL | 注释

2-注释 2.1-单行注释 select prod_name -- 这是一条行内注释 from products; 使用两个连字符(-- ) 放在行内&#xff0c;两个连字符后的内容即为注释内容。 # 这是一条注释 select prod_name from products; 这种注释方式可能有些数据库不支持&#xff0c;所以使用前应该…

shiro框架基本概念介绍

目录 什么是Shiro: Shiro的核心功能包括&#xff1a; Shiro主要组件及相互作用&#xff1a; Shiro 认证过程&#xff1a; Shiro 授权过程&#xff1a; 资料获取方法 什么是Shiro: Shiro 是一个强大灵活的开源安全框架&#xff0c;可以完全处理身份验证、授权、加密和会话…

funbox3靶场渗透笔记

funbox3靶场渗透笔记 靶机地址 https://download.vulnhub.com/funbox/Funbox3.ova 信息收集 fscan找主机ip192.168.177.199 .\fscan64.exe -h 192.168.177.0/24___ _/ _ \ ___ ___ _ __ __ _ ___| | __/ /_\/____/ __|/ __| __/ _ |/ …

单源最短路的扩展应用

选择最佳线路 有一天&#xff0c;琪琪想乘坐公交车去拜访她的一位朋友。 由于琪琪非常容易晕车&#xff0c;所以她想尽快到达朋友家。 现在给定你一张城市交通路线图&#xff0c;上面包含城市的公交站台以及公交线路的具体分布。 已知城市中共包含 n 个车站&#xff08;编号…

Azure概念介绍

云计算定义 云计算是一种使用网络进行存储和处理数据的计算方式。它通过将数据和应用程序存储在云端服务器上&#xff0c;使用户能够通过互联网访问和使用这些资源&#xff0c;而无需依赖于本地硬件和软件。 发展历史 云计算的概念最早可以追溯到20世纪60年代的时候&#x…

Stable Diffusion WebUI安装和使用教程(Windows)

目录 下载Stable Diffusion WebUI运行安装程序&#xff0c;双击webui.bat界面启动插件安装&#xff08;github&#xff09;模型下载(有些需要魔法&#xff09;安装过程遇到的大坑总结参考的博客 整个过程坑巨多&#xff0c;我花了一个晚上的时间才全部搞定,本教程针对有编程基础…

网络设备(防火墙、路由器、交换机)日志分析监控

外围网络设备&#xff08;如防火墙、路由器、交换机等&#xff09;是关键组件&#xff0c;因为它们控制进出公司网络的流量。因此&#xff0c;监视这些设备的活动有助于 IT 管理员解决操作问题&#xff0c;并保护网络免受攻击者的攻击。通过收集和分析这些设备的日志来监控这些…

苹果Mac像Windows一样使用

一、将磁盘访问设置的像Windows一样&#xff1a; 1.1、点击任务栏第一个按钮打开“访达”&#xff0c;点击菜单栏上的访达-偏好设置&#xff1a; 1.2、勾选“硬盘”&#xff0c;这样macOS的桌面上就会显示一个本地磁盘&#xff0c;之后重命名为磁盘根&#xff0c;相当于window…

部署Springboot项目注意事项

步骤 步骤 1&#xff1a;将数据库内容在云服务器上的数据库部署一份 我使用mariadb&#xff1b;会出现一些不兼容现象&#xff1b;我们需要把默认值删掉 2&#xff1a;配置文件你得修改地方 a&#xff1a;linux是磁盘区分(像我自己项目用来储存验证码的文件我们得换这个配置;…

Spring_AOP

一、AOP简介 AOP&#xff0c;Aspect Oriented Programming,面向切面编程,是对面向对象编程0OP的升华。OOP是纵向对一个事物的抽象&#xff0c;一个对象包括静态的属性信息&#xff0c;包括动态的方法信息等。而AOP是横向的对不同事物的抽象,属性与属性、方法与方法、对象与对象…

cs231n assignment2 q5 PyTorch on CIFAR-10

文章目录 嫌啰嗦直接看源码Q5 :PyTorch on CIFAR-10three_layer_convnet题面解析代码输出 Training a ConvNet题面解析代码输出 ThreeLayerConvNet题面解析代码输出 Train a Three-Layer ConvNet题面解析代码输出 Sequential API: Three-Layer ConvNet题面解析代码输出 CIFAR-1…

【MongoDB】解决ProxmoxVE下CentOS7虚拟机安装MongoDB6后启动失败的问题

目录 安装步骤&#xff1a; 2.1 配置yum源 2.2 安装MongoDB 2.3 启 动MongoDB ProxmoxVE上新装的CentOS7.4虚拟机&#xff0c;安装MongoDB6。 安装步骤&#xff1a; 2.1 配置yum源 # 创建mongodb yum源&#xff08;https://www.mongodb.com/docs/manual/tutorial/insta…

27岁了学plc还来得及吗?

如果你是学电气或者自控&#xff0c;完全没问题&#xff0c;PLC其实只是你的理解力的问题&#xff0c;真正底层的&#xff0c;都帮你打包了&#xff0c;你直接用就是。问题只是&#xff1a;你要能透彻理解 如果你从一个完全陌生的行业转过来&#xff0c;完全没必要。如果本身就…

[数据分析与可视化] Python绘制数据地图5-MovingPandas绘图实例

MovingPandas是一个基于Python和GeoPandas的开源地理时空数据处理库&#xff0c;用于处理移动物体的轨迹数据。关于MovingPandas的使用见文章&#xff1a;MovingPandas入门指北&#xff0c;本文主要介绍三个MovingPandas的绘图实例。 MovingPandas官方仓库地址为&#xff1a;mo…