WebSocket的原理及QT示例

一.WebSocket 介紹

1.概述

WebSocket 是一種在單個 TCP 連接上進行全雙工通訊的協議,它在 2011 年被 IETF 定為標準 RFC 6455,并由 RFC7936 補充規范。與傳統的 HTTP 協議不同,WebSocket 允許服務器和客戶端之間進行實時、雙向的數據傳輸,打破了 HTTP 協議請求 - 響應的模式限制,大大提高了數據傳輸的效率和實時性。

2.特點

全雙工通信:服務器和客戶端可以在任意時刻向對方發送數據,無需等待對方的請求。

實時性強:由于采用了全雙工通信,數據可以即時傳輸,非常適合實時性要求較高的應用場景,如在線聊天、實時數據監控等。

較少的開銷:WebSocket 握手階段使用 HTTP 協議,建立連接后,數據傳輸不再需要像 HTTP 那樣攜帶大量的頭部信息,減少了數據傳輸的開銷。

跨域支持:WebSocket 支持跨域通信,方便不同域名之間的服務器和客戶端進行數據交互。

客戶端與服務器交互圖

3.應用場景

實時聊天應用:如在線客服、社交聊天等,用戶可以即時收到對方發送的消息。

實時數據監控:如股票行情、傳感器數據監控等,服務器可以實時將最新的數據推送給客戶端。

多人在線游戲:實現游戲中玩家之間的實時交互,如位置更新、動作同步等。

二.代碼示例

1.客戶端代碼

#include "Clientdialog.h"

#include <QLabel>

#include <QWidget>

#include <QHBoxLayout>

#include <QVBoxLayout>

#include <QtCore>

#include <QDebug>

#include <iostream>

ClientDialog::ClientDialog(QWidget *parent)

????: QWidget(parent)

{

????//layout1

????QLabel *iplabel = new QLabel("Server IP");

????m_iplineedit =new QLineEdit;

????m_iplineedit->setText("127.0.0.1");

????QLabel *portlabel =new QLabel("Server端口");

????m_portspinbox = new QSpinBox;

????m_portspinbox->setRange(0,65535);

????m_portspinbox->setValue(5123);

????m_linkbutton = new QPushButton("連接");

????m_disconnectbutton = new QPushButton("斷開");

????pButtonGroup = new QButtonGroup();

????pButtonGroup->setExclusive(true);

????m_linkbutton->setCheckable(true);

????m_disconnectbutton->setCheckable(true);

????pButtonGroup->addButton(m_linkbutton,0);

????pButtonGroup->addButton(m_disconnectbutton,1);

????QHBoxLayout *qhboxlayout1 = new QHBoxLayout;

????qhboxlayout1->addWidget(iplabel);

????qhboxlayout1->addWidget(m_iplineedit);

????qhboxlayout1->addWidget(portlabel);

????qhboxlayout1->addWidget(m_portspinbox);

????qhboxlayout1->addWidget(m_linkbutton);

????qhboxlayout1->addWidget(m_disconnectbutton);

????//layout2

????QLabel *sendmessagelabel = new QLabel("發送消息");

????QHBoxLayout *qhboxlayout2 = new QHBoxLayout;

????qhboxlayout2->addWidget(sendmessagelabel);

????//layout3

????m_sendmessagetextedit = new QTextEdit;

????m_sendmessagetextedit->setFixedHeight(50);

????m_sendbutton = new QPushButton("發送");

????m_sendbutton->setFixedHeight(50);

????QHBoxLayout *qhboxlayout3 = new QHBoxLayout;

????qhboxlayout3->addWidget(m_sendmessagetextedit);

????qhboxlayout3->addWidget(m_sendbutton);

????//layout4

????QLabel *receivemessagelabel = new QLabel("接收消息");

????QHBoxLayout *qhboxlayout4 = new QHBoxLayout;

????qhboxlayout4->addWidget(receivemessagelabel);

????//layout5

????m_receivemessageTextEdit = new QTextEdit;

????QHBoxLayout *qhboxlayout5 = new QHBoxLayout;

????qhboxlayout5->addWidget(m_receivemessageTextEdit);

????m_receivemessageTextEdit->setReadOnly(true);

????//layout6

????statusLabel = new QLabel("連接狀態");

????m_clean = new QPushButton("清除");

????QHBoxLayout *qhboxlayout6 = new QHBoxLayout;

????qhboxlayout6->addWidget(statusLabel);

????qhboxlayout6->addStretch();

????qhboxlayout6->addWidget(m_clean);

????//

????QVBoxLayout *mainlayout = new QVBoxLayout;

????mainlayout->addLayout(qhboxlayout1,1);

????mainlayout->addLayout(qhboxlayout2,0.5);

????mainlayout->addLayout(qhboxlayout3,1);

????mainlayout->addLayout(qhboxlayout4,0.5);

????mainlayout->addLayout(qhboxlayout5,3);

????mainlayout->addLayout(qhboxlayout6,1);

????setLayout(mainlayout);

????setWindowTitle("Websocket Client");

????this->setFixedSize(800, 600); // 窗口固定為800x600像素,無法縮放

????connect(m_linkbutton,SIGNAL(clicked(bool)),this,SLOT(connectToServer()));

????connect(m_disconnectbutton,SIGNAL(clicked(bool)),this,SLOT(stopClicked()));

????connect(m_sendbutton,SIGNAL(clicked(bool)),this,SLOT(onSendButtonClicked()));

????connect(m_clean,SIGNAL(clicked(bool)),this,SLOT(onCleanButtonClicked()));

????connect(&m_websocket,SIGNAL(connected()),this,SLOT(onconnected()));

????connect(&m_websocket,SIGNAL(disconnected()),this,SLOT(closeConnection()));

????connect(&m_websocket,SIGNAL(textMessageReceived(QString)),this,SLOT(onTextMessageReceived(QString)));

}

ClientDialog::~ClientDialog()

{

????m_websocket.errorString();

????m_websocket.close();

}

//斷開連接操作

void ClientDialog::closeConnection(){

????m_linkbutton->setEnabled(true);

????m_disconnectbutton->setEnabled(false);

????m_sendmessagetextedit->setEnabled(false);

????m_sendbutton->setEnabled(false);

????m_receivemessageTextEdit->setEnabled(false);

????m_clean->setEnabled(false);

????statusLabel->setText(tr("disconnected"));

}

//連接服務器

void ClientDialog::connectToServer()

{

????QString path = QString("ws://%1:%2").arg(m_iplineedit->text()).arg(m_portspinbox->text());

????QUrl url = QUrl(path);

????m_websocket.open(url);

}

//連接上之后

void ClientDialog::onconnected(){

????qDebug() << "hello word!";

????statusLabel->setText(tr("connected"));

????m_linkbutton->setEnabled(false);

????m_disconnectbutton->setEnabled(true);

????m_sendmessagetextedit->setEnabled(true);

????m_sendbutton->setEnabled(true);

????m_receivemessageTextEdit->setEnabled(true);

????m_clean->setEnabled(true);

}

//收到消息

void ClientDialog::onTextMessageReceived(const QString &message)

{

????QString time = current_date_time->currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz ddd");

????m_receivemessageTextEdit->setText(time + "\r\n" + "message: " + message);

}

//斷開

void ClientDialog::stopClicked()

{

????m_websocket.close();

}

//發送消息

void ClientDialog::onSendButtonClicked()

{

????QString msg= m_sendmessagetextedit->document()->toPlainText();

????m_websocket.sendTextMessage(msg);

}

//清除內容

void ClientDialog::onCleanButtonClicked()

{

????m_receivemessageTextEdit->clear();

}

2.服務端代碼

#include "webserver.h"

#include "ui_webserver.h"

#include <QtCore/QVariant>

#include <QtWidgets/QApplication>

#include <QtWidgets/QButtonGroup>

#include <QtWidgets/QHeaderView>

#include <QtWidgets/QLabel>

#include <QtWidgets/QListWidget>

#include <QtWidgets/QPushButton>

#include <QtWidgets/QSpinBox>

#include <QtWidgets/QTextBrowser>

#include <QtWidgets/QWidget>

#include <QHBoxLayout>

webserver::webserver(QWidget *parent) :

????QWidget(parent),

????ui(new Ui::webserver)

{

????ui->setupUi(this);

????{

?????????//qhboxLayout1部分代碼

?????????QLabel* monitorLabel= new QLabel("監聽端口");

?????????m_monitorSpinBox = new QSpinBox();

?????????m_monitorSpinBox->setRange(0,65535);

?????????m_monitorSpinBox->setValue(5123);

?????????m_startButton = new QPushButton("啟動服務");

?????????m_stopButton = new QPushButton("停止服務");

?????????m_stopButton->setEnabled(false);

?????????QHBoxLayout *qhboxLayout = new QHBoxLayout;

?????????qhboxLayout->addWidget(monitorLabel);

?????????qhboxLayout->addWidget(m_monitorSpinBox);

?????????qhboxLayout->addWidget(m_startButton);

?????????qhboxLayout->addWidget(m_stopButton);

????????//qhboxLayout2部分代碼

??????????QLabel* sendLabel=new QLabel("發送消息");

??????????sendLabel->setFixedHeight(30);

??????????QHBoxLayout *qhboxLayout2 = new QHBoxLayout;

??????????qhboxLayout2->addWidget(sendLabel);

????????//qhboxLayout3部分代碼

??????????m_sendTextedit = new QTextEdit;

??????????m_sendTextedit = new QTextEdit();

??????????m_sendTextedit->setEnabled(false);

??????????m_sendTextedit->setFixedHeight(80);

??????????m_sendButton= new QPushButton("發送");

??????????m_sendButton->setEnabled(false);

??????????m_sendButton->setFixedHeight(50);

??????????QHBoxLayout *qhboxlayout3 = new QHBoxLayout;

??????????qhboxlayout3->addWidget(m_sendTextedit,2);

??????????qhboxlayout3->addWidget(m_sendButton,1);

????????//qvboxlayout411

??????????QLabel* receiveLabel = new QLabel("接收消息");

??????????receiveLabel->setFixedHeight(30);

??????????m_receiveTextEdit = new QTextEdit();

??????????m_receiveTextEdit->setReadOnly(true);

??????????QVBoxLayout *qvboxlayout411 = new QVBoxLayout;

??????????qvboxlayout411->addWidget(receiveLabel);

??????????qvboxlayout411->addWidget(m_receiveTextEdit);

????????????//qhboxlayout412

??????????m_cleanButton = new QPushButton("清除");

??????????m_cleanButton->setEnabled(false);

??????????QHBoxLayout *qhboxlayout412 = new QHBoxLayout;

??????????qhboxlayout412->addStretch();

??????????qhboxlayout412->addWidget(m_cleanButton);

????????//qvboxlayout41

??????????QVBoxLayout *qvboxlayout41 = new QVBoxLayout;

??????????qvboxlayout41->addLayout(qvboxlayout411);

??????????qvboxlayout41->addLayout(qhboxlayout412);

????????//qvboxlayout42

??????????QLabel* linkclientLabel=new QLabel("連接客戶端");

??????????linkclientLabel->setFixedHeight(30);

??????????m_linkclientListWidget=new QListWidget;

??????????QVBoxLayout* qvboxlayout42 = new QVBoxLayout;

??????????qvboxlayout42->addWidget(linkclientLabel);

??????????qvboxlayout42->addWidget(m_linkclientListWidget);

????????//qvboxlayout4

??????????QHBoxLayout *qhboxlayout4 = new QHBoxLayout;

??????????qhboxlayout4->addLayout(qvboxlayout41,2);

??????????qhboxlayout4->addLayout(qvboxlayout42,1);

?????????//mainlayout

??????????QVBoxLayout *mainLayout = new QVBoxLayout;

??????????mainLayout->addLayout(qhboxLayout,1);

??????????mainLayout->addLayout(qhboxLayout2,1);

??????????mainLayout->addLayout(qhboxlayout3,1);

??????????mainLayout->addLayout(qhboxlayout4,3);

??????????this->setLayout(mainLayout);

??????????this->setWindowTitle("Websocket Server -- Neo");

??????????this->setFixedSize(800, 600); // 窗口固定為800x600像素,無法縮放

????}

????m_WebSocketServer=new QWebSocketServer("server",QWebSocketServer::NonSecureMode);

????connect(m_WebSocketServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));

????connect(m_WebSocketServer, SIGNAL(closed()), this, SLOT(onClosed()));

????connect(m_WebSocketServer, SIGNAL(serverError(QWebSocketProtocol::CloseCode)),

????????????this, SLOT(onServerError(QWebSocketProtocol::CloseCode)));

????connect(m_startButton,SIGNAL(clicked(bool)),this,SLOT(onStartButtonClick()));

????connect(m_stopButton,SIGNAL(clicked(bool)),this,SLOT(onStopButtonClick()));

????connect(m_cleanButton,SIGNAL(clicked(bool)),this,SLOT(onCleanButtonClick()));

????connect(m_sendButton,SIGNAL(clicked(bool)),this,SLOT(onSendButtonClick()));

}

webserver::~webserver()

{

????if(m_WebSocketServer)

????{

????????m_WebSocketServer->close();

????}

????delete ui;

}

//開啟服務

void webserver::onStartButtonClick(){

????int i_port = m_monitorSpinBox->text().toInt();

????m_WebSocketServer->listen(QHostAddress::Any,i_port);

????m_startButton->setEnabled(false);

????m_stopButton->setEnabled(true);

????qDebug()<<m_WebSocketServer->isListening();

????qDebug()<<m_WebSocketServer->serverPort();

????qDebug()<<m_WebSocketServer->serverAddress();

}

//停止服務

void webserver::onStopButtonClick(){

????m_startButton->setEnabled(true);

????m_stopButton->setEnabled(false);

????m_WebSocketServer->close();

}

//發送信息

void webserver::onSendButtonClick(){

????QString msg = m_sendTextedit->document()->toPlainText();

????int currenRow = m_linkclientListWidget->currentRow();//當前單擊選中ListWidget控件的行號

????if(currenRow==-1)

????{

????????currenRow = 0;

????}

????QString key = m_linkclientListWidget->item(currenRow)->text();

????if(_hashIpPort2PWebSocket.contains(key))

????{

????????_hashIpPort2PWebSocket.value(key)->sendTextMessage(msg);

????}

}

void webserver::onCleanButtonClick(){

????m_receiveTextEdit->clear();

}

//連接上之后

void webserver::onNewConnection(){

????qDebug() << "connect ok";

????m_startButton->setEnabled(false);

????m_stopButton->setEnabled(true);

????m_sendTextedit->setEnabled(true);

????m_sendButton->setEnabled(true);

????m_cleanButton->setEnabled(true);

????QWebSocket *pWebSocket = m_WebSocketServer->nextPendingConnection();

????connect(pWebSocket,SIGNAL(textMessageReceived(QString)),this,SLOT(slot_processTextMessage(QString)));

????connect(pWebSocket,SIGNAL(disconnected()),this,SLOT(slot_socketDisconnected()));

????connect(pWebSocket, SIGNAL(error(QAbstractSocket::SocketError)),

????????????this ?????, SLOT(slot_error(QAbstractSocket::SocketError)));

????quint32 ipv4Address = ?pWebSocket->peerAddress().toIPv4Address();

????QString ipString = QHostAddress(ipv4Address).toString();

????_hashIpPort2PWebSocket.insert(QString("%1-%2").arg(ipString).arg(pWebSocket->peerPort()),pWebSocket);

????QString item = QString("%1-%2").arg(ipString).arg(pWebSocket->peerPort());

????m_linkclientListWidget->addItem(item);

}

//停止之后

void webserver::onClosed()

{

????QList<QWebSocket *> _listWebSocket = _hashIpPort2PWebSocket.values();

????for(int index = 0; index < _listWebSocket.size(); index++)

????{

????????_listWebSocket.at(index)->close();

????}

????_hashIpPort2PWebSocket.clear();

????m_linkclientListWidget->clear();

}

//連接錯誤

void webserver::onServerError(QWebSocketProtocol::CloseCode closeCode)

{

????QWebSocket *pWebSocket = dynamic_cast<QWebSocket *>(sender());

????if(!pWebSocket)

????{

????????return;

????}

}

void webserver::slot_error(QAbstractSocket::SocketError error)

{

????QWebSocket *pWebSocket = dynamic_cast<QWebSocket *>(sender());

????if(!pWebSocket)

????{

????????return;

????}

}

//收到消息并顯示

void webserver::slot_processTextMessage(QString message){

????QWebSocket *pWebSocket = dynamic_cast<QWebSocket *>(sender());

????if(!pWebSocket)

????{

????????return;

????}

????QString time = current_date_time->currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz ddd");

????quint32 ipv4Address = ?pWebSocket->peerAddress().toIPv4Address();

????QString ipString = QHostAddress(ipv4Address).toString();

????QString item = QString("IP: %1, port: %2").arg(ipString).arg(pWebSocket->peerPort());

????m_receiveTextEdit->append(time+ "\r\n" + item + "\r\n" + "message: " + message + "\r\n");

????//qDebug()<< pWebSocket->peerAddress().toString();

????//qDebug() << "Client IP address: " << ipString;

}

//連接斷開的操作

void webserver::slot_socketDisconnected(){

????QWebSocket *pWebSocket = dynamic_cast<QWebSocket *>(sender());

????if(!pWebSocket)

????{

????????return;

????}

????//qDebug() << __FILE__ << __LINE__ << __FUNCTION__;

????quint32 ipv4Address = ?pWebSocket->peerAddress().toIPv4Address();

????QString ipString = QHostAddress(ipv4Address).toString();

????QString item1 = QString("%1-%2").arg(ipString).arg(pWebSocket->peerPort());

????_hashIpPort2PWebSocket.remove(QString("%1-%2").arg(ipString).arg(pWebSocket->peerPort()));

????QListWidgetItem *item3;

????for(int i=0;i<m_linkclientListWidget->count();i++)

????{

????????QString str = m_linkclientListWidget->item(i)->text();

????????if(str == item1)

????????{

????????????item3 = m_linkclientListWidget->takeItem(i);

????????????m_linkclientListWidget->removeItemWidget(item3);

????????????delete item3;

????????}

????}

}

void webserver::on_m_linkclientListWidget_clicked(const QModelIndex &index)

{

int currenRow = m_linkclientListWidget->currentRow();

}

3.完整工程代碼下載

https://download.csdn.net/download/xieliru/90787178

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/905273.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/905273.shtml
英文地址,請注明出處:http://en.pswp.cn/news/905273.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

設置GO程序在離線情況下讀取本地緩存的模塊

在 Go 中&#xff0c;GOPROXY 環境變量用于指定模塊代理服務器的地址。如果你想讓 GOPROXY 讀取本地的模塊&#xff0c;可以通過以下幾種方式實現&#xff1a; 1. 使用本地代理服務器 你可以搭建一個本地的 Go 模塊代理服務器&#xff0c;將需要的模塊代碼推送到代理服務器中…

live555開發筆記(三):live555創建RTSP服務器源碼剖析,創建h264文件rtsp服務器源碼深度剖析

若該文為原創文章&#xff0c;轉載請注明原文出處 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/147879917 長沙紅胖子Qt&#xff08;長沙創微智科&#xff09;博文大全&#xff1a;開發技術集合&#xff08;包含Qt實用技術、樹莓派、三維、OpenCV…

STM32-模電

目錄 一、MOS管 二、二極管 三、IGBT 四、運算放大器 五、推挽、開漏、上拉電阻 一、MOS管 1. MOS簡介 這里以nmos管為例&#xff0c;注意箭頭方向。G門極/柵極&#xff0c;D漏極&#xff0c;S源極。 當給G通高電平時&#xff0c;燈泡點亮&#xff0c;給G通低電平時&a…

基于定制開發開源AI智能名片S2B2C商城小程序的公私域流量融合運營策略研究

摘要&#xff1a;本文以定制開發開源AI智能名片S2B2C商城小程序為技術載體&#xff0c;系統探討公域流量向私域流量沉淀的數字化路徑。研究通過分析平臺流量&#xff08;公域流量&#xff09;與私域流量的共生關系&#xff0c;提出"公域引流-私域沉淀-數據反哺"的閉環…

mysql中索引的使用

前言 最近一直在學習mysql以及忙學校課程的事情。已經好久沒寫過博客了&#xff0c;今天跟大家分享一下在mysql中關于索引的知識&#xff0c;希望可以幫助到大家。 索引的定義 mysql中的索引是一種數據結構&#xff0c;它可以幫助數據庫高效地查詢&#xff0c;更新數據表中的…

深度拆解!MES如何重構生產計劃與排產調度全流程?

?引言 在制造業數字化轉型浪潮中&#xff0c;生產計劃與排產調度的精準性直接決定企業競爭力。深藍易網MES系統通過智能化調度與全流程管控&#xff0c;幫助企業破解排產難題&#xff0c;實現資源高效協同與生產透明化管理&#xff0c;為制造企業打造柔性化、敏捷化的生產體系…

【深度學習】計算機視覺(18)——從應用到設計

文章目錄 1 不同的注意力機制1.1 自注意力1.2 多頭注意力1.3 交叉注意力1.3.1 基礎1.3.2 進階 1 不同的注意力機制 在學習的過程中&#xff0c;發現有很多計算注意力的方法&#xff0c;例如行/列注意力、交叉注意力等&#xff0c;如果對注意力機制本身不是特別實現&#xff0c…

洛谷 P1955 [NOI2015] 程序自動分析

【題目鏈接】 洛谷 P1955 [NOI2015] 程序自動分析 【題目考點】 1. 并查集 2. 離散化 【解題思路】 多組數據問題&#xff0c;對于每組數據&#xff0c;有多個 x i x j x_ix_j xi?xj?或 x i ≠ x j x_i \neq x_j xi?xj?的約束條件。 所有相等的變量構成一個集合&…

[Java] 輸入輸出方法+猜數字游戲

目錄 1. 輸入輸出方法 1.1 輸入方法 1.2 輸出方法 2. 猜數字游戲 1. 輸入輸出方法 Java中輸入和輸出是屬于Scanner類里面的方法&#xff0c;如果要使用這兩種方法需要引用Scanner類。 import java.util.Scanner; java.util 是Java里面的一個包&#xff0c;里面包含一些工…

zst-2001 上午題-歷年真題 UML(13個內容)

UML基礎 UML - 第1題 ad UML - 第2題 依賴是暫時使用對象&#xff0c;關聯是長期連接 依賴&#xff1a;依夜情 關聯&#xff1a;天長地久 組合&#xff1a;組一輩子樂隊 聚合&#xff1a;好聚好散 bd UML - 第3題 adc UML - 第4題 bad UML - 第5題 d UML…

WebFlux vs WebMVC vs Servlet 對比

WebFlux vs WebMVC vs Servlet 技術對比 WebFlux、WebMVC 和 Servlet 是 Java Web 開發中三種不同的技術架構&#xff0c;它們在編程模型、并發模型和適用場景上有顯著區別。以下是它們的核心對比&#xff1a; 核心區別總覽 特性ServletSpring WebMVCSpring WebFlux編程模型…

htmlUnit和Selenium的區別以及使用BrowserMobProxy捕獲網絡請求

1. Selenium&#xff1a;瀏覽器自動化之王 核心定位&#xff1a; 跨平臺、跨語言的瀏覽器操控框架&#xff0c;通過驅動真實瀏覽器實現像素級用戶行為模擬。 技術架構&#xff1a; 核心特性&#xff1a; 支持所有主流瀏覽器&#xff08;含移動端模擬&#xff09; 精…

SSRF相關

SSRF(Server Side Request Forgery,服務器端請求偽造)&#xff0c;攻擊者以服務器的身份發送一條構造好的請求給服務器所在地內網進行探測或攻擊。 產生原理&#xff1a; 服務器端提供了能從其他服務器應用獲取數據的功能&#xff0c;如從指定url獲取網頁內容、加載指定地址的圖…

SaaS備份的必要性:廠商之外的數據保護策略

在當今數字化時代&#xff0c;企業對SaaS&#xff08;軟件即服務&#xff09;應用的依賴程度不斷攀升。SaaS應用為企業提供了便捷的生產力工具&#xff0c;然而&#xff0c;這也使得數據安全面臨諸多挑戰&#xff0c;如意外刪除、勒索軟件攻擊以及供應商故障等。因此&#xff0…

【Python 基礎語法】

Python 基礎語法是編程的基石&#xff0c;以下從核心要素到實用技巧進行系統梳理&#xff1a; 一、代碼結構規范 縮進規則 使用4個空格縮進&#xff08;PEP 8標準&#xff09;縮進定義代碼塊&#xff08;如函數、循環、條件語句&#xff09; def greet(name):if name: # 正確縮…

利用“Flower”實現聯邦機器學習的實戰指南

一個很尷尬的現狀就是我們用于訓練 AI 模型的數據快要用完了。所以我們在大量的使用合成數據&#xff01; 據估計&#xff0c;目前公開可用的高質量訓練標記大約有 40 萬億到 90 萬億個&#xff0c;其中流行的 FineWeb 數據集包含 15 萬億個標記&#xff0c;僅限于英語。 作為…

自動化測試與功能測試詳解

&#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 什么是自動化測試? 自動化測試是指利用軟件測試工具自動實現全部或部分測試&#xff0c;它是軟件測試的一個重要組成 部分&#xff0c;能完成許多手工測試無…

MySQL全量,增量備份與恢復

目錄 一.MySQL數據庫備份概述 1.數據備份的重要性 2.數據庫備份類型 3.常見的備份方法 二&#xff1a;數據庫完全備份操作 1.物理冷備份與恢復 2.mysqldump 備份與恢復 3.MySQL增量備份與恢復 3.1MySQL增量恢復 3.2MySQL備份案例 三&#xff1a;定制企業備份策略思路…

Ubuntu 安裝 Nginx

Nginx 是一個高性能的 Web 服務器和反向代理服務器&#xff0c;同時也可以用作負載均衡器和 HTTP 緩存。 Nginx 的主要用途 用途說明Web服務器提供網頁服務&#xff0c;處理用戶的 HTTP 請求&#xff0c;返回 HTML、CSS、JS、圖片等靜態資源。反向代理服務器將用戶請求轉發到…

人工智能 機器學習期末考試題

自測試卷2 一、選擇題 1&#xff0e;下面哪個屬性不是NumPy中數組的屬性&#xff08; &#xff09;。 A&#xff0e;ndim B&#xff0e;size C&#xff0e;shape D&#xff0e;add 2&#xff0e;一個簡單的Series是由&#xff08; &#xff09;的數據組成的。 A&#xff0e;兩…