QT里的网络通信简介

news2024/9/23 3:16:14

QTcpSocket类简介

QTcpSocket类提供了一个TCP套接字。TCP(传输控制协议)是一种可靠的、面向流的、面向连接的传输协议。它特别适合数据的连续传输。QTcpSocket是QAbstractSocket的一个子类,它允许您建立TCP连接和传输数据流。有关详细信息,请参阅QAbstractSocket文档。(注意:不能在QIODevice::Unbuffered模式下打开TCP套接字。)

header:#include
qmake: QT += network
Inherits: QAbstractSocket
Inherited By: QSctpSocket and QSslSocket

公共函数:(继承的比较多,下面就介绍它自己的以及QAbstractSocket里的)

QTcpSocket(QObject *parent = nullptr)
//创建状态为UnconnectedState的QTcpSocket对象。
virtual  ~QTcpSocket()
//销毁套接字,必要时关闭连接。
QAbstractSocket(QAbstractSocket::SocketType socketType, QObject *parent)
//创建类型为SocketType的新抽象套接字。
virtual  ~QAbstractSocket()
//销毁套接字
void  abort()
//中止当前连接并重置套接字。与disconnectFromHost()不同,此函数会立即关闭套接字,丢弃写缓冲区中的任何挂起数据。
bool  bind(const QHostAddress &address, quint16 port = 0, QAbstractSocket::BindMode mode = DefaultForPlatform)
//使用绑定模式绑定到端口端口上的地址。
//对于UDP套接字,绑定后,每当UDP数据报到达指定的地址和端口时,就会发出信号QUdpSocket::readyRead()。因此,此函数对于写入UDP服务器很有用。
//对于TCP套接字,此函数可用于指定用于传出连接的接口,这在多个网络接口的情况下很有用。
//默认情况下,套接字是使用DefaultForPlatform绑定模式绑定的。如果未指定端口,则会选择一个随机端口。
//成功后,函数返回true,套接字进入BoundState;否则返回false。此功能在Qt 5.0中引入。
bool  bind(quint16 port = 0, QAbstractSocket::BindMode mode = DefaultForPlatform)
//这是一个重载函数。
//绑定到QHostAddress:任何端口上的端口,使用BindMode模式。
//默认情况下,套接字是使用DefaultForPlatform绑定模式绑定的。如果未指定端口,则会选择一个随机端口。
virtual void connectToHost(const QString &hostName, quint16 port, QIODevice::OpenMode openMode = ReadWrite, QAbstractSocket::NetworkLayerProtocolprotocol = AnyIPProtocol)
//尝试连接到给定端口上的hostName。协议参数可用于指定要使用的网络协议(例如IPv4或IPv6)。
//套接字在给定的openMode中打开,首先进入HostLookupState,然后执行hostName的主机名查找。如果查找成功,将发出hostFound(),并且QAbstractSocket将进入ConnectingState。然后,它尝试连接到查找返回的一个或多个地址。最后,如果建立了连接,QAbstractSocket将进入ConnectedState并发出connected()。
//在任何时候,套接字都可以发出error()来发出发生错误的信号。
//hostName可以是字符串形式的IP地址(例如“43.195.83.32”),也可以是主机名(例如“example.com”)。只有在需要时,x才会进行查找。端口按本机字节顺序排列。
virtual void connectToHost(const QHostAddress &address, quint16 port, QIODevice::OpenMode openMode = ReadWrite)
//这是一个重载函数。尝试连接到端口端口上的地址。
virtual void disconnectFromHost()
//试图关闭套接字。如果有挂起的数据等待写入,QAbstractSocket将进入ClosingState并等待,直到所有数据都已写入。最终,它将进入UnconnectedState并发出disconnected()信号。
QAbstractSocket::SocketError error() const
//返回上次发生的错误类型。
bool flush()
//此函数在不阻塞的情况下,尽可能多地从内部写入缓冲区写入底层网络套接字。如果写入了任何数据,此函数将返回true;否则返回false。
//如果需要QAbstractSocket立即开始发送缓冲数据,请调用此函数。成功写入的字节数取决于操作系统。在大多数情况下,您不需要调用此函数,因为一旦控制返回到事件循环,QAbstractSocket将自动开始发送数据。如果没有事件循环,请改为调用waitForBytesWritten()。
bool isValid() const
//如果套接字有效并且可以使用,则返回true;否则返回false。
//注意:在进行读取和写入之前,套接字的状态必须为ConnectedState。
QHostAddress  localAddress() const
//返回本地套接字的主机地址(如果可用);否则返回QHostAddress::Null。
//这通常是主机的主IP地址,但对于连接到本地主机,可以是QHostAddress::LocalHost(127.0.0.1)。
quint16 localPort() const
//返回本地套接字的主机端口号(按本机字节顺序)(如果可用);否则返回0。
QAbstractSocket::PauseModes pauseMode() const
//返回此套接字的暂停模式。此功能在Qt 5.0中引入。
QHostAddress peerAddress() const
//如果套接字处于ConnectedState,则返回连接的对等方的地址;否则返回QHostAddress::Null。
QString peerName() const
//返回由connectToHost()指定的对等方的名称,如果尚未调用connectToHost(),则返回空的QString。
quint16 peerPort() const
//如果套接字处于ConnectedState,则返回已连接对等端的端口;否则返回0。
QNetworkProxy proxy() const
//返回此套接字的网络代理。默认情况下,使用QNetworkProxy::DefaultProxy,这意味着此套接字将查询应用程序的默认代理设置。此功能在Qt 4.1中引入。
qint64 readBufferSize() const
//返回内部读取缓冲区的大小。这限制了客户端在调用read()或readAll()之前可以接收的数据量。
//读取缓冲区大小为0(默认值)意味着缓冲区没有大小限制,确保不会丢失任何数据。
virtual void resume()
//在套接字上继续数据传输。只有在套接字设置为在收到通知时暂停并且收到通知后,才应使用此方法。当前支持的唯一通知是QSslSocket::sslErrors()。如果套接字未暂停,则调用此方法会导致未定义的行为。此功能在Qt 5.0中引入。
void setPauseMode(QAbstractSocket::PauseModes pauseMode)
//控制是否在收到通知时暂停。pauseMode参数指定套接字应该暂停的条件。当前支持的唯一通知是QSslSocket::sslErrors()。如果设置为PauseOnslErrors,套接字上的数据传输将暂停,并且需要通过调用resume()再次显式启用。默认情况下,此选项设置为PauseNever。在连接到服务器之前必须调用此选项,否则将导致未定义的行为。此功能在Qt 5.0中引入。
void setProxy(const QNetworkProxy &networkProxy)
//将此套接字的显式网络代理设置为networkProxy。
virtual void setReadBufferSize(qint64 size)
//将QAbstractSocket的内部读取缓冲区的大小设置为size字节。
//如果缓冲区大小被限制为某个特定的大小,那么QAbstractSocket不会缓冲超过这个大小的数据。例外情况下,缓冲区大小为0意味着读取缓冲区是不受限制的,并且缓冲所有传入数据。这是默认设置。
//如果您只在特定时间点读取数据(例如,在实时流应用程序中),或者如果您想保护套接字不接收过多数据,这可能最终导致应用程序内存不足,则此选项非常有用。
//只有QTcpSocket使用QAbstractSocket的内部缓冲区;QUdpSocket根本不使用任何缓冲,而是依赖于操作系统提供的隐式缓冲。因此,在QUdpSocket上调用此函数没有任何效果。
virtual bool setSocketDescriptor(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = ConnectedState, QIODevice::OpenMode openMode = ReadWrite)
//使用本机套接字描述符socketDescriptor初始化QAbstractSocket。如果socketDescriptor被接受为有效的套接字描述符,则返回true;否则返回false。套接字以openMode指定的模式打开,并进入socketState指定的套接字状态。读取和写入缓冲区被清除,丢弃任何挂起的数据。
//注意:不可能使用相同的本机套接字描述符初始化两个抽象套接字。
virtual void setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value)
//将给定option设置为由value描述的值。
//注意:在Windows运行时上,连接套接字之前必须设置QAbstractSocket::KeepAliveOption。
//此功能在Qt 4.6中引入。
virtual qintptr socketDescriptor() const
//如果QAbstractSocket对象的本地套接字描述符可用,则返回该描述符;否则返回-1。
//如果套接字使用QNetworkProxy,则返回的描述符可能无法用于本机套接字函数。
//当QAbstractSocket处于UnconnectedState时,套接字描述符不可用。
virtual QVariant socketOption(QAbstractSocket::SocketOption option)
//返回option选项的值。此功能在Qt 4.6中引入。
QAbstractSocket::SocketType socketType() const
//返回套接字类型(TCP、UDP或其他)。
QAbstractSocket::SocketState state() const
//返回套接字的状态。
virtual bool waitForConnected(int msecs = 30000)
//等待,直到套接字连接,最长可达毫秒。如果已建立连接,则此函数将返回true;否则返回false。在返回false的情况下,可以调用error()来确定错误的原因。
virtual bool waitForDisconnected(int msecs = 30000)
//等待,直到套接字断开连接,最长可达毫秒。如果连接已断开,此函数将返回true;否则返回false。在返回false的情况下,可以调用error()来确定错误的原因。

静态公共成员:
QMetaObject
包含了QObject的所谓的元数据,也就是QObject信息的一些描述信息:除了类型信息外,还包含QT中特有的signal&slot信息。

QTcpSocket类使用

// 定义套接字
QTcpServer *socket = new QTcpSocket();

//取消已有的连接
socket->abort();

//连接服务器
socket->connectToHost(IP, Port);

//QTcpSocket类里读取和发送数据用的函数都在socket缓冲区中保存
//读取socket缓冲区数据
QString buffer = socket->readAll();
//写入socket缓冲区里数据
socket->write("将数据写入socket缓存区");
//可以以以下两个信号来添加槽函数处理操作
//连接成功和连接断开会触发 connected() 和 disconnected() 信号:
//当socket接收缓冲区有新数据到来时,会发出readRead()信号

//断开连接
socket->disconnectFromHost();

//关闭套接字
socket.close();

QTcpServer类简介
QTcpServer类提供了一个基于TCP的服务器。此类可以接受传入的TCP连接。可以指定端口,也可以让QTcpServer自动选择一个端口。可以监听特定的地址或所有机器的地址。调用listen()让服务器监听传入的连接。每次客户端连接到服务器时,都会发出newConnection()信号。调用nextPendingConnection()以接受挂起的连接作为已连接的QTcpSocket。该函数返回指向QAbstractSocket::ConnectedState中QTcpSocket的指针,您可以使用该指针与客户端通信。如果发生错误,serverError()将返回错误类型,并且可以调用errorString()来获得所发生事情的可读描述。在侦听连接时,服务器正在侦听的地址和端口可用作serverAddress()和serverPort()。调用close()将使QTcpServer停止侦听传入连接。尽管QTcpServer主要是为与事件循环一起使用而设计的,但也可以在没有事件循环的情况下使用它。在这种情况下,您必须使用waitForNewConnection(),它会阻塞直到连接可用或超时。

Header:#include
qmake: QT += network
Inherits: QObject
Inherited By: QSctpServer

Public Functions

QTcpServer(QObject *parent = nullptr)
//构造一个QTcpServer对象。
virtual ~QTcpServer()
//销毁QTcpServer对象。
void close()
//关闭服务器。服务器将不再侦听传入连接。
QString errorString() const
//返回上次发生的错误的可读说明。
virtual bool hasPendingConnections() const
//如果服务器有挂起的连接,则返回true;否则返回false。
bool isListening() const
//如果服务器当前正在侦听传入连接,则返回true;否则返回false。
bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
//告诉服务器侦听地址地址和端口端口上的传入连接。如果端口为0,则自动选择端口。如果地址为QHostAddress::Any,则服务器将侦听所有网络接口。成功时返回true;否则返回false。
int maxPendingConnections() const
//返回挂起的可接受连接的最大数目。默认值为30。
virtual QTcpSocket *nextPendingConnection()
//将下一个挂起的连接作为已连接的QTcpSocket对象返回。
//套接字是作为服务器的子级创建的,这意味着当QTcpServer对象被销毁时,它会被自动删除。在处理完对象后显式删除该对象仍然是一个好主意,以避免浪费内存。
//如果在没有挂起的连接时调用此函数,则返回0。
//注意:返回的QTcpSocket对象不能从另一个线程使用。如果要使用来自另一个线程的传入连接,则需要重写incomingConnection()。
void pauseAccepting()
//暂停接受新连接。排队的连接将保留在队列中。
QNetworkProxy proxy() const
//返回此套接字的网络代理。默认情况下,使用QNetworkProxy::DefaultProxy。
void resumeAccepting()
//继续接受新连接。
QHostAddress serverAddress() const
//如果服务器正在侦听连接,则返回服务器的地址;否则返回QHostAddress::Null。
QAbstractSocket::SocketError serverError() const
//返回上次发生的错误的错误代码。
quint16 serverPort() const
//如果服务器正在侦听连接,则返回服务器的端口;否则返回0。
void setMaxPendingConnections(int numConnections)
//将挂起的可接受连接的最大数量设置为numConnections。在调用nextPendingConnection()之前,QTcpServer将接受不超过numConnections的传入连接。默认情况下,限制为30个挂起的连接。
//在服务器达到其挂起连接的最大数量后,客户端仍然可以连接(即,QTcpSocket仍然可以发出connected()信号)。QTcpServer将停止接受新连接,但操作系统可能仍会将它们保留在队列中。
void setProxy(const QNetworkProxy &networkProxy)
//将此套接字的显式网络代理设置为networkProxy。
bool setSocketDescriptor(qintptr socketDescriptor)
//设置此服务器在侦听到socketDescriptor的传入连接时应使用的套接字描述符。如果套接字设置成功,则返回true;否则返回false。
//假定套接字处于侦听状态。
qintptr socketDescriptor() const
//返回服务器用于侦听传入指令的本机套接字描述符,如果服务器未在侦听,则返回-1。
//如果服务器正在使用QNetworkProxy,则返回的描述符可能无法用于本机套接字函数。
bool waitForNewConnection(int msec = 0, bool *timedOut = nullptr)
//等待时间最多为毫秒,或者直到有传入连接可用为止。如果连接可用,则返回true;否则返回false。如果操作超时且timedOut不为0,则*timedOut将设置为true。
//这是一个阻塞函数调用。它在单线程GUI应用程序中的使用是不利的,因为整个应用程序将停止响应,直到函数返回。waitForNewConnection()在没有可用的事件循环时非常有用。
//非阻塞的替代方法是连接到newConnection()信号。
//如果毫秒为-1,则此功能不会超时。

此外还有31 public functions inherited from QObject 

Signals

void acceptError(QAbstractSocket::SocketError socketError)
//当接受新连接导致错误时,会发出此信号。socketError参数描述了发生的错误类型。
void newConnection()
//每当有新的连接可用时,就会发出此信号。

此外还有2 signals inherited from QObject 

QTcpServer类使用

QTcpServer *server = new QTcpServer();

//监听指定的地址和端口
server->listen(QHostAddress::Any, port)

//获取已经连接的客户端套接字
socket = server->nextPendingConnection(); 

//关闭倾听服务
server->close();

小练习:
在这里插入图片描述

//client.h
#ifndef CLIENT_H
#define CLIENT_H
#pragma execution_character_set("utf-8")
#include <QMainWindow>
#include <QTcpSocket>
#include <QKeyEvent>
#include <QWidget>

namespace Ui {
	class client;
}

class Client : public QMainWindow
{
	Q_OBJECT

public:
	explicit Client(QWidget *parent = nullptr);
	~Client();

private slots:
	void on_connect_button_clicked(bool checked);

	void on_send_button_clicked();

	void readyRead_SLOT();

	void connected_SLOT();

private:
	Ui::client *ui;
	QTcpSocket *socket;
};

#endif // CLIENT_H
//server.h
#ifndef SERVER_H
#define SERVER_H
#pragma execution_character_set("utf-8")
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QString>

QT_BEGIN_NAMESPACE
namespace Ui { class Server; }
QT_END_NAMESPACE

class Server : public QMainWindow
{
	Q_OBJECT

public:
	Server(QWidget *parent = nullptr);
	~Server();

private slots:
	void on_send_button_clicked();

	void on_startorstop_Listen_clicked(bool checked);

	void readyRead_SLOT();
	
	void newConnection_SLOT();

private:
	Ui::Server *ui;
	QTcpSocket *socket;
	QTcpServer *server;
};
#endif // SERVER_H
//client.cpp
#include "client.h"
#include "ui_client.h"
#include "stdio.h"
#include "QString"
#include <QTextCodec>
#pragma execution_character_set("utf-8")
Client::Client(QWidget *parent) :
	QMainWindow(parent),
	ui(new Ui::client)
{
	
	ui->setupUi(this);
	//设置clicked(bool checked)点击反转状态打开
	ui->connect_button->setCheckable(true);

	socket = new QTcpSocket();

	//信号:客户端申请连接成功 槽函数:允许写入数据
	connect(socket, SIGNAL(connected()), this, SLOT(connected_SLOT()));
}

Client::~Client()
{
	delete ui;
}

//信号:客户端申请连接成功 槽函数:允许写入数据
void Client::connected_SLOT()
{
	connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead_SLOT()));//如果socket中有缓存消息,触发槽函数
}

//接收消息并显示到接收框
void Client::readyRead_SLOT()
{
	
	
	QString buffer;
	qDebug() << "Client Received!";
	//读取缓冲区数据
	buffer = socket->readAll();
	buffer = "Server: " + buffer;
	if (!buffer.isEmpty())
	{
		qDebug() << buffer;
		//刷新显示
		ui->receiver->appendPlainText(buffer);
	}
}

//连接和断开按键
void Client::on_connect_button_clicked(bool checked)
{
	if (checked)
	{
		QString IP = ui->ipnum->text();
		int Port = ui->portnum->text().toUInt();
		//取消已有的连接
		socket->abort();
		//连接服务器
		socket->connectToHost(IP, Port);
		//如果等待超过1000ms
		if (!socket->waitForConnected(1000))
		{
			qDebug() << "Connect failed, please try again later!";
			//连接失败,再次点击则重新连接,将checked恢复为true
			ui->connect_button->toggle();
			return;
		}
		qDebug() << "Connect Successfully! Connect with IP:" << IP << "; port:" << Port;
		//修改按键文字
		ui->connect_button->setText("断开连接");
		//发送键使能
		ui->send_button->setEnabled(true);
	}
	else
	{
		qDebug() << "Disconnect!";
		//断开连接
		socket->disconnectFromHost();
		//修改按键文字&发送键静默
		ui->connect_button->setText("连接");
		ui->send_button->setEnabled(false);
	}
}

//发送消息,写入socket缓存区
void Client::on_send_button_clicked()
{
	//qDebug() << "Client Send: " << ui->sender->toPlainText().toLocal8Bit();
	将输入框的内容写入socket缓冲区
	//socket->write(ui->sender->toPlainText().toLocal8Bit());
	qDebug() << "Client Send: " << ui->sender->toPlainText().toLatin1();
	ui->receiver->appendPlainText("client: " + ui->sender->toPlainText());
	//将输入框的内容写入socket缓冲区
	socket->write(ui->sender->toPlainText().toLatin1());
	//刷新socket缓冲区
	socket->flush();
	ui->sender->setPlainText("");
}
//server.cpp
#include "server.h"
#include "ui_server.h"
#include <QTextCodec>
Server::Server(QWidget *parent)
	: QMainWindow(parent)
	, ui(new Ui::Server)
{
	ui->setupUi(this);
	//设置clicked(bool checked)点击反转状态打开
	ui->startorstop_Listen->setCheckable(true);

	socket = new QTcpSocket();
	server = new QTcpServer();

	//信号:新的客户端连接建立 槽函数:获取客户端套接字,允许写入数据
	connect(server, SIGNAL(newConnection()), this, SLOT(newConnection_SLOT()));
}

Server::~Server()
{
	delete ui;
}

//信号:新的客户端连接建立 槽函数:获取客户端套接字,允许写入数据
void Server::newConnection_SLOT()
{
	socket = server->nextPendingConnection(); //获取已经连接的客户端套接字
	connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead_SLOT()));//如果socket中有缓存消息,触发槽函数
}

//接收消息并显示到接收框
void Server::readyRead_SLOT()
{

	qDebug() << "Server Received!";
	QString buffer;
	//读取缓冲区数据
	buffer = socket->readAll();
	buffer = "Client:  " + buffer;
	if (!buffer.isEmpty())
	{
		//刷新显示
		ui->receiver->appendPlainText(buffer);
	}
}


//开始监听和停止监听按键
void Server::on_startorstop_Listen_clicked(bool checked)
{
	if (checked)
	{
		int port = ui->portnum->text().toUInt();
		//如果未监听到
		if (!server->listen(QHostAddress::Any, port))
		{
			qDebug() << server->errorString();
			//连接失败,再次点击则重新连接,将checked恢复为true
			ui->startorstop_Listen->toggle();
			return;
		}
		qDebug() << "Listen Successfully! Message from port:" << port;
		//修改按钮文字
		ui->startorstop_Listen->setText("停止监听");
		//发送键使能
		ui->send_button->setEnabled(true);
	}
	else
	{
		qDebug() << "Stop Listening!";
		//如果已经连接则断开连接
		if (socket->state() == QAbstractSocket::ConnectedState)
		{
			//断开连接
			socket->disconnectFromHost();
		}
		//关闭倾听服务
		server->close();
		//修改按钮文字&发送键静默
		ui->startorstop_Listen->setText("开始监听");
		ui->send_button->setEnabled(false);
	}
}

//发送消息,写入socket缓存区
void Server::on_send_button_clicked()
{
	//qDebug() << "Client Send: " << ui->sender->toPlainText().toLocal8Bit();
	将输入框的内容写入socket缓冲区
	//socket->write(ui->sender->toPlainText().toLocal8Bit());
	qDebug() << "Server Send: " << ui->sender->toPlainText().toLatin1();
	ui->receiver->appendPlainText("server: " + ui->sender->toPlainText());
	//将输入框的内容写入socket缓冲区
	socket->write(ui->sender->toPlainText().toLatin1());
	//刷新socket缓冲区
	socket->flush();
	ui->sender->setPlainText("");
}
//main()
#include "server.h"
#include "client.h"
#include <QApplication>

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	Server w1;
	Client w2;

	//Client窗口通过鼠标单机获得聚焦
	w2.setFocusPolicy(Qt::ClickFocus);
	//将客户端和服务端窗口移动到屏幕合适位置
	w1.move(320, 340);
	w2.move(960, 340);

	//打开客户端和服务端窗口
	w1.show();
	w2.show();

	return a.exec();
}

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

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

相关文章

连接器信号完整性仿真教程 二

在连接器信号完整性仿真教程一中Step by Step演示了如何进行连接器信号完整性仿真&#xff0c;看完这片博文后应该可以做类似产品的仿真。如果说&#xff0c;看了这篇博文就学会了连接器信号完整性仿真&#xff0c;那就有点过了。有人也许会说信号完整性仿真难学&#xff0c;不…

利用GPT2 预测 福彩3d预测

使用GPT2预测福彩3D项目 个人总结彩票数据是随机的,可以预测到1-2个数字,但是有一两位总是随机的 该项目紧做模型学习用,通过该项目熟练模型训练调用生成过程. 福彩3D数据下载 https://www.17500.cn/getData/3d.TXT data数据格式 处理后数据格式 每行 2023 03 08 9 7 3 训…

Java入门教程||Java 继承||Java 重写(Override)与重载(Overload)

Java 继承 继承是所有 OOP 语言和 Java 语言不可缺少的组成部分。 继承是 Java 面向对象编程技术的一块基石&#xff0c;是面向对象的三大特征之一&#xff0c;也是实现软件复用的重要手段&#xff0c;继承可以理解为一个对象从另一个对象获取属性的过程。 如果类 A 是类 B …

玩机搞机----mtk芯片机型 另类制作备份线刷包的方式 读写分区等等

前面分享了几期高通和mtk芯片机型备份字库的几种方法教程。这些针对与很多没有线刷包资源的手机机型玩机操作。前面对接一个友商的mtk芯片杂牌机。和另外一个国外mtk芯片级都是来制作线刷包。因为&#xff0c;这些机型没有固件流出。而同一批机型中安卓版本高低不固定。支持的资…

谷歌TAG警告说俄罗斯黑客在乌克兰进行网络钓鱼攻击

与俄罗斯军事情报机构有关的精英黑客与针对乌克兰数百名用户的大批量网络钓鱼活动有关&#xff0c;以提取情报并影响与战争有关的公共言论。 谷歌的威胁分析小组&#xff08;TAG&#xff09;正在监测这个名为FROZENLAKE的行为者的活动&#xff0c;该小组表示&#xff0c;这些攻…

3105—IIS部署子站点

一、父站点 1—web.config配置 新增并设定location段落 <configuration><location path"." allowOverride"false" inheritInChildApplications"false"><system.webServer><handlers><add name"aspNetCore"…

科海思除COD树脂,大孔树脂,除COD专用树脂

一、产品介绍 Tulsimer A-722 MP具有控制孔径的大孔强碱性Ⅰ型阴离子交换树脂 Tulsimer A-722 MP 是一款具有便于颜色和有机物去除的控制孔径的&#xff0c;专门开发的大孔强碱性Ⅰ型阴离子交换树脂。 Tulsimer A-722 MP&#xff08;氯型&#xff09;专门应用于去除COD…

Vite与WebPack的对比,及解决了什么痛点,及什么是ESM?

一、简要 ESM&#xff0c;是指构成ESM规范的一系列的JavaScript特性或者API 1、首先要明确的是&#xff0c;Vite跟WebPack的优势只在开发环境。当把包部署到了生产环境后&#xff0c;大家都是一样的&#xff0c;甚至webpack的兼容性可能会更好。 这也是为什么有人提出&#x…

图像描述算法排位赛:SceneXplain 与 MiniGPT4 谁将夺得桂冠?

如果你对图像描述算法的未来感到好奇&#xff0c;本场“图像描述算法排位赛”绝对是你不能错过的&#xff01;在这场较量中&#xff0c;SceneXplain 和 MiniGPT-4 将会比试&#xff0c;谁将摘得这场比赛的桂冠&#xff1f; 背景介绍 在上篇文章中&#xff0c;我们介绍了图像描述…

C++类与对象—上

本期我们来学习类与对象 目录 面向过程和面向对象初步认识 类的引入 访问限定符 类的定义 封装 类的作用域 类的实例化 this指针 C语言和C实现Stack的对比 面向过程和面向对象初步认识 C 语言是 面向过程 的&#xff0c; 关注 的是 过程 &#xff0c;分析出求解问题的…

研究生考试 之 计算机网络第七版(谢希仁) 第一章 课后答案

研究生考试 之 计算机网络第七版(谢希仁) 第一章 课后答案 目录 研究生考试 之 计算机网络第七版(谢希仁) 第一章 课后答案 一、简单介绍 二、计算机网络第七版(谢希仁) 第一章 课后答案 1、 计算机网络向用户可以提供哪些服务&#xff1f; 2、 试简述分组交换的要点。 3…

人工神经网络

&#x1f351; CV专栏 1. 单个神经元 &#x1f351; 神经网络 即 模型 &#x1f364; 输入 四个参数 --> 结果 &#x1f351; 模型训练(学习) 例子 &#x1f351; 模型的输入x 乘 权值ω 减去阈值θ --> 激活函数 f &#x1f351; 输出 yi &#xff08;向下传递 或 直…

一步步带你学习Python编程:从零开始的查缺补漏

在快节奏的生活中&#xff0c;很难找到时间来学习新的技能。但有时候&#xff0c;我们会突然发现自己有一些空闲时间&#xff0c;而又不想虚度光阴。无聊的时候&#xff0c;我们可以选择学习一项新技能来充实自己。最近&#xff0c;我就因为有些无聊&#xff0c;决定重新学习Py…

linux实现网络程序

1️⃣ 在linux下&#xff0c;通过套接字实现服务器和客户端的通信。 2️⃣ 实现单线程、多线程通信。或者实现线程池来通信。 3️⃣ 优化通信&#xff0c;增加守护进程。 有情提醒&#xff0c;类里面默认的函数是内联。内联函数在调用的地方展开&#xff0c;没有函数地址&…

【Springboot系列】Springboot整合Swagger3不简单

1、缘由 Swagger是一个根据代码注解生成接口文档的工具&#xff0c;减少和前端之间的沟通&#xff0c;前端同学看着文档就可以开发了&#xff0c;提升了效率&#xff0c;之前很少写swagger&#xff0c;这次自己动手写&#xff0c;还是有点麻烦&#xff0c;不怎么懂&#xff0c;…

外网SSH远程连接linux服务器「cpolar内网穿透」

文章目录 视频教程1. Linux CentOS安装cpolar2. 创建TCP隧道3. 随机地址公网远程连接4. 固定TCP地址5. 使用固定公网TCP地址SSH远程 转载自内网穿透工具的文章&#xff1a;无公网IP&#xff0c;SSH远程连接Linux CentOS服务器【内网穿透】 本次教程我们来实现如何在外公网环境下…

OpenGL入门教程之 纹理

引言 我们已经了解到&#xff0c;我们可以为每个顶点添加颜色来增加图形的细节&#xff0c;从而创建出有趣的图像。但是&#xff0c;如果想让图形看起来更真实&#xff0c;我们就必须有足够多的顶点&#xff0c;从而指定足够多的颜色。这将会产生很多额外开销&#xff0c;因为每…

【ArcGIS Pro二次开发】(23):用地编码和用地名称的规范性检查

在国空或村庄规划的编制过程中&#xff0c;随着规划用地的调整&#xff0c;经常会手动修改用地编码和用地名称&#xff0c;不可避免的会出现错误&#xff0c;如果单靠人工校对&#xff0c;累人又不能保证准确性。这个工具的目的就是检查用地编码和用地名称是否规范&#xff0c;…

最短路径Floyd与区间DP

floyd算法是求最短路径的算法&#xff0c;算法复杂度为n(o^3),其优点在于能够一次求解所有点到其他点的最短路径&#xff0c;不需要其他运算&#xff0c;使用二维数组存储。其三层循环自外向内分别为&#xff1a;中间点&#xff0c;起始点和终点。状态方程为&#xff1a; num[…

【社区图书馆】《网络工程师的Python之路:网络运维自动化实战(第2版)》

文章目录 图书前言图书简介图书作者、简介图书好评图书目录总结&#xff1a;本人选择此图书的意义 图书前言 光阴似箭&#xff0c;岁月如梭。转眼之间&#xff0c;距离本书最早的电子书出版已经过去了三年之久。承蒙广大读者的厚爱&#xff0c;电子书和第1版纸质书的发行量远远…