網絡與通信

1.TCP協議與UDP協議

TCP(Transmission Control Protocol,傳輸控制協議)和 UDP(User Datagram Protocol,用戶數據報協議)是 TCP/IP 協議族中兩種核心的傳輸層協議,它們在數據傳輸方式、可靠性、適用場景等方面有顯著區別。

1、核心區別對比

特性TCPUDP
連接方式面向連接(需先建立連接)無連接(直接發送數據)
可靠性可靠傳輸(保證數據完整、有序到達)不可靠傳輸(不保證送達,可能丟失)
傳輸效率較低(需處理確認、重傳等機制)較高(無額外控制開銷)
數據邊界無(流式傳輸,需應用層處理邊界)有(以數據報為單位,一次發送一個完整報文)
擁塞控制支持(避免網絡擁堵)不支持
首部開銷較大(固定 20 字節,可擴展)較小(固定 8 字節)
適用場景文件傳輸、網頁瀏覽、郵件等視頻通話、實時游戲、廣播等

2、TCP 協議詳解

1. 核心特點:面向連接、可靠傳輸
  • 連接建立:通過 “三次握手” 建立連接(類似打電話確認雙方可通信)

    • 客戶端發送 SYN(請求連接)
    • 服務器回復 SYN+ACK(同意連接)
    • 客戶端回復 ACK(確認連接建立)
  • 可靠傳輸機制

    • 序號與確認機制:每個數據包有編號,接收方收到后需返回確認(ACK),未確認則重傳
    • 重傳機制:發送方超時未收到確認則重傳數據
    • 流量控制:通過滑動窗口限制發送速率,避免接收方緩沖區溢出
    • 擁塞控制:根據網絡狀況動態調整發送速率(慢啟動、擁塞避免等算法)
  • 連接終止:通過 “四次揮手” 關閉連接(確保雙方數據都已傳輸完畢)

2. 工作流程示例(文件傳輸)
  1. 客戶端向服務器發起連接請求(三次握手)
  2. 連接建立后,客戶端分塊發送文件數據
  3. 服務器每收到一塊數據就返回確認
  4. 若某塊數據丟失,客戶端超時后重傳
  5. 所有數據傳輸完成,雙方通過四次揮手關閉連接
3. 優缺點
  • 優點:數據可靠、有序,適合對準確性要求高的場景
  • 缺點:延遲較高(握手、確認等耗時),開銷大

3、UDP 協議詳解

1. 核心特點:無連接、不可靠傳輸
  • 無連接:發送數據前無需建立連接,直接封裝數據并發送(類似郵寄信件)
  • 不可靠
    • 不保證數據送達(無確認機制)
    • 不保證順序(數據包可能亂序到達)
    • 不處理重傳(丟失數據需應用層自行處理)
  • 數據報傳輸:每個 UDP 報文獨立發送,接收方一次讀取一個完整報文
2. 工作流程示例(視頻通話)
  1. 客戶端直接向服務器發送視頻幀數據(無需提前建立連接)
  2. 服務器收到數據后直接交給應用層處理
  3. 若部分數據包丟失,應用層可選擇忽略(避免卡頓)或請求重傳關鍵幀
  4. 通信結束無需 “關閉連接”,直接停止發送即可
3. 優缺點
  • 優點:傳輸速度快、延遲低、開銷小,適合實時性要求高的場景
  • 缺點:數據可能丟失、亂序,需應用層自行處理可靠性

4、適用場景對比

協議典型應用選擇原因
TCP網頁(HTTP/HTTPS)、文件傳輸(FTP)、郵件(SMTP)需保證數據完整、準確,允許一定延遲
UDP視頻通話(如 Zoom)、實時游戲、DNS 查詢、廣播需低延遲,可容忍少量數據丟失

總結:TCP就像打電話,需要先接通,建立聯系,確保雙方能同時接收或發送數據,而UDP更像送快遞,雖然速度快,但是會有數據丟失的風險.

2.IP地址

1.IP地址的概念

IP 地址(Internet Protocol Address,互聯網協議地址)是互聯網中用于唯一標識網絡設備(如計算機、路由器、服務器、手機等)的數字標簽,相當于設備在網絡中的 “門牌號碼”。所有網絡通信(如瀏覽網頁、發送消息、下載文件)都依賴 IP 地址來定位目標設備,確保數據能準確從 “發送方” 傳輸到 “接收方”。

一、核心作用:定位與路由

IP 地址的核心功能可拆解為兩點:

  1. 設備標識:在全球或局部網絡中,每個設備的 IP 地址具有唯一性(同一網絡內絕對唯一,全球范圍內通過路由規則確保不沖突),避免數據傳錯目標。
  2. 路由指引:數據在網絡中傳輸時,路由器會根據 IP 地址中的 “網絡段” 信息,判斷數據應轉發到哪個子網,最終導向目標設備(類似快遞根據 “省 - 市 - 區” 分層投遞)。
二、IP 地址的兩大版本:IPv4 與 IPv6

目前主流的 IP 地址分為兩個版本,核心差異在于地址長度、容量和格式,本質是為解決 “地址耗盡” 問題(IPv4 地址不夠用)。

對比維度IPv4(互聯網協議第 4 版)IPv6(互聯網協議第 6 版)
地址長度32 位(二進制)128 位(二進制)
地址格式點分十進制(如?192.168.1.1冒分十六進制(如?2001:0db8:85a3:0000:0000:8a2e:0370:7334
地址容量約 42.9 億個(232),已基本耗盡約 3.4×103?個(212?),足夠支撐未來百年
配置方式需手動配置或 DHCP 自動分配支持自動配置(無狀態地址自動配置 SLAAC)
安全性無內置安全機制,需依賴 TCP 或應用層(如 SSL)內置 IPsec 協議,原生支持加密和身份驗證
主流程度目前仍廣泛使用(占比超 90%)逐步推廣(物聯網、5G 場景優先部署)
三、IPv4 地址的結構與分類(重點)

IPv4 是目前最常用的版本,其 32 位地址分為 “網絡位” 和 “主機位” 兩部分:

  • 網絡位:標識設備所屬的 “子網”(類似 “小區地址”);
  • 主機位:標識子網內的具體設備(類似 “小區內的門牌號”)。

為區分網網絡位,后 8 位是主機位)。

1. IPv4 地址的分類(傳統分類,便于初期管理)

IPv4 根據首段數字(第 1 個十進制數)分為 5 類,其中 A、B、C 類為 “單播地址”(用于單個設備通信絡位和主機位,IPv4 通過子網掩碼(Subnet Mask)?標記(如?255.255.255.0?表示前 24 位是),D 類為 “組播地址”(一對多通信,如視頻會議),E 類為 “保留地址”(未公開使用)。

地址類別首段數字范圍網絡位長度主機位長度適用場景示例
A 類1~1268 位24 位大型網絡(如早期互聯網主干)10.0.0.1(私有地址)
B 類128~19116 位16 位中型網絡(如企業內網)172.16.0.1(私有)
C 類192~22324 位8 位小型網絡(如家庭 / 辦公室)192.168.1.1(私有)
D 類224~239-(無分類)-組播通信224.0.0.1(所有主機)
E 類240~255--科研保留無公開示例
2. 特殊 IPv4 地址(需重點記憶)
  • 回環地址(Loopback Address)127.0.0.1~127.255.255.254,用于設備 “自身測試”(如瀏覽器訪問?127.0.0.1?可測試本地服務器是否正常),數據不會發送到外部網絡。
  • 私有地址(Private Address):僅用于內網通信,無法直接訪問互聯網(需通過路由器的 NAT 技術轉換為公網 IP),避免公網地址浪費。常見私有地址段:
    • A 類:10.0.0.0~10.255.255.255
    • B 類:172.16.0.0~172.31.255.255
    • C 類:192.168.0.0~192.168.255.255(家庭路由器默認網段多為此類,如?192.168.1.1
  • 廣播地址(Broadcast Address):子網內 “所有設備” 的地址(如子網?192.168.1.0/24?的廣播地址是?192.168.1.255),發送到該地址的數據會被子網內所有設備接收。
四、IP 地址的獲取方式

設備不會天生擁有 IP 地址,需通過以下方式獲取:

  1. 靜態配置(Static IP):手動在設備(如服務器、打印機)上設置 IP 地址、子網掩碼、網關等參數,適合需要固定地址的場景(如網站服務器,確保用戶能穩定訪問)。
  2. 動態配置(Dynamic IP):通過DHCP 協議(動態主機配置協議)?自動獲取地址,由路由器或 DHCP 服務器分配臨時 IP(租期通常幾小時到幾天),到期后可重新分配。家庭手機、電腦等設備默認使用此方式,無需手動設置。
五、公網 IP 與內網 IP 的區別

這是實際使用中最易混淆的概念,核心差異在于 “是否能被互聯網直接訪問”:

  • 公網 IP:由運營商(如聯通、電信)分配的 “全球唯一地址”,可直接被互聯網上的其他設備訪問(如網站服務器的 IP?202.108.22.5,任何人都能通過該地址訪問百度)。
  • 內網 IP:僅用于局域網(如家庭 WiFi、公司內網)的私有地址(如?192.168.1.100),無法被互聯網直接訪問。內網設備要訪問互聯網,需通過路由器的NAT 轉換(將內網 IP 轉換為公網 IP),類似 “小區所有住戶共用一個大門牌號”。

總結:

3. socket套接字

在網絡編程中,socket()?函數是創建套接字(Socket)的核心接口,用于初始化一個網絡通信端點.

1. socket () 函數的核心作用

socket()?函數用于創建一個套接字對象,該對象是后續網絡通信(如連接、發送、接收數據)的基礎。調用后會返回一個套接字描述符(或對象引用),后續操作都通過這個描述符進行。

2. socket()函數的四個參數

import socket

# socket.socket 一共四個參數:

# 第一個參數:地址族,AF_INET表示使用IPv4協議,AF_INET6表示使用IPv6協議

# 第二個參數:套接字類型,SOCK_STREAM表示流式套接字,SOCK_DGRAM表示數據報式套接字

# 第三個參數:協議,一般不用設置,默認為0。也可以指定

# 第四個參數:本地地址,一般不用設置,默認為None。

# 第一個參數

# AF_UNIX(Adress Family,即地址族 unix)

# AF_INET(Adress Family,即地址族 internet)

# AF_INET6 用于 IPv6 地址(未來也許會用到)

# AF_BLUETOOTH 用于藍牙地址

# AF_CAN 用于 CAN 總線地址

# 第二個參數

# SOCK_STREAM(Socket Type,即套接字類型,流式套接字)

# SOCK_DGRAM(Socket Type,即套接字類型,數據報式套接字)

# 第三個參數(2種示例)

# TCP(Transmission Control Protocol,即傳輸控制協議)

# SOCK_STREAM(Socket Type,即套接字類型,流式套接字)

# 協議:TCP

_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM,socket.IPPROTO_TCP)

# UDP(User Datagram Protocol,即用戶數據報協議)

# SOCK_DGRAM(Socket Type,即套接字類型,數據報式套接字)

# 協議:UDP

_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,socket.IPPROTO_UDP)

4. TCP通信

1.TCP單向通信(一個發一個收)

1.TCP服務器代碼

import socketif __name__ =='__main__':server_socket =socket.socket(socket.AF_INET,socket.SOCK_STREAM)host ='127.0.0.1'port =8888server_socket.bind((host,port))server_socket.listen(5)client_socket,arrr =server_socket.accept()while True:data = client_socket.recv(1024).decode('utf-8')print(f"Receive from client: {data}")if data =="exit":message =="exit"client_socket.send(message.encode('utf-8'))breakelif data =="?":message ="你在?什么"client_socket.send(message.encode('utf-8'))else:client_socket.send('0'.encode('utf-8'))client_socket.close()server_socket.close()print("Server has stopped")

2. TCP客戶端代碼

import socketif __name__ =='__main__':client_socket =socket.socket(socket.AF_INET,socket.SOCK_STREAM)host ="127.0.0.1"port =8888client_socket.connect((host,port))while True:message =input("請輸入:")client_socket.sendall(message.encode('utf-8'))mag =client_socket.recv(1024)if mag != b'0':print('對方發送的信息:',mag.decode('utf-8'))if message=="exit":breakclient_socket.close()

代碼解析:

我們這里需要開兩個不同的終端,保證兩個終端能夠建立起鏈接,這里兩個終端各自有自己的任務

  • 服務器:啟動后監聽本地 8888 端口,等待客戶端連接。連接建立后,接收客戶端發送的消息,并根據消息內容做出響應:
    • 收到 "exit" 時,斷開連接并停止服務
    • 收到 "?" 時,回復 "你在?什么"
    • 收到其他消息時,回復 "0"
  • 客戶端:連接到服務器后,可循環輸入消息發送給服務器,同時接收服務器的響應,輸入 "exit" 時斷開連接

2.TCP雙向通信(可以互相發送和接收)
注意:如果要實現雙向通信是需要用到多線程的

1.TCP服務端代碼

'''
1, 并發通信,實現多個客戶端連接服務器
2, 實現全雙工通信,服務端與客戶端可以同時接收發數據
'''
import os
import signal
import socket
import threadingdef handle_signal(signum, frame):print('received signal {}'.format(signum))exit(0)#接收線程
def recv_data(socket):while True:recv_buffer = socket.recv(1024).decode('utf-8')if not recv_buffer:print('client is quit!')print(f'recv data from client: {recv_buffer}')if recv_buffer == 'exit':print('received exit from client')break#發送線程
def send_data(socket):while True:message = input('please input your message:')socket.send(message.encode('utf-8'))if message == 'exit':os.kill(os.getpid(), signal.SIGTERM)if __name__ == '__main__':#1, 創建socketserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#2, 綁定端口host = socket.gethostname()port = 5002server_socket.bind((host, port))#3, 監聽server_socket.listen(5)print('server is starting....., waiting for a connection')#4, 接收客戶端連接client_socket, addr = server_socket.accept()print('Got connection from', addr)#4, 創建2個線程實現與客戶端通信recv_thread = threading.Thread(target=recv_data,args=(client_socket,))send_thread = threading.Thread(target=send_data,args=(client_socket,))recv_thread.start()send_thread.start()# 4, 注冊一個信號signal.signal(signal.SIGTERM, handle_signal)#5, 等待線程結束recv_thread.join()send_thread.join()#6, 關閉套接字server_socket.close()client_socket.close()

2.TCP客戶端代碼

'''
客戶端
'''
import os
import socket
import threading
import signal#1, 接收線程
def recv_data(socket):while True:recv_buffer = socket.recv(1024).decode('utf-8')if not recv_buffer:print('server is quit!')breakprint(f'recv data from server {recv_buffer}')if recv_buffer == 'exit':print('received exit from server')# 終止進程os.kill(os.getpid(), signal.SIGTERM)#2, 發送線程
def send_data(socket):global recv_thread_flagwhile True:send_buffer = input('please input your data: ')socket.send(send_buffer.encode('utf-8'))if send_buffer == 'exit':#終止進程os.kill(os.getpid(), signal.SIGTERM)def handle_signal(signum, frame):print('received signal {}'.format(signum))exit(0)if __name__ == '__main__':#1, 創建socketclient_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#2, 建立連接host = '127.0.0.1'port = 5002client_socket.connect((host, port))#3, 創建2個線程實現與server端通信recv_thread = threading.Thread(target=recv_data,args=(client_socket,))send_thread = threading.Thread(target=send_data,args=(client_socket,))#4, 注冊一個信號signal.signal(signal.SIGTERM,handle_signal)#4, 等待線程結束recv_thread.start()send_thread.start()#5, 關閉socketrecv_thread.join()send_thread.join()#6, 關閉套接字client_socket.close()

代碼解析:
我們這里需要開兩個不同的終端,保證兩個終端能夠建立起鏈接,這里兩個終端各自有自己的任務,與上面相比就是多了線程的部分,然后要實現不同設備之間的通信也是如此,還需要修改IP地址即可建立連接,如果使用公網的情況下,可能會造成無法連接的情況,這個時候我們可以讓兩個設備鏈接到同一個手機熱點上,再綁定IP地址.

  • 客戶端:通過兩個線程分別處理接收和發送數據,實現同時收發(全雙工),支持輸入消息發送給服務器,也能實時接收服務器消息,輸入 "exit" 可退出。
  • 服務器:能監聽并接受多個客戶端連接(通過循環接受連接實現),對每個連接也用兩個線程處理收發數據,實現與客戶端的全雙工通信。

總結:如果是單方面傳送數據的話只需要socket一個就行,一個負責發送,一個負責接收,但是在這個建立連接的過程,需要經過三次握手建立連接,否則我們不能知道是否已經連接上了,然后如果是雙向傳輸接收數據的話,就需要多加一個多線程thread,在每個里面加入一個發送線程一個接收線程

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

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

相關文章

Node.js中package.json詳解

1. name(名稱) 如果你計劃發布你的包,package.json 中最重要的字段是 name 和 version,因為它們是必需的。name 和 version 共同組成一個假定完全唯一的標識符。包的更改應伴隨版本號的更新。如果你不打算發布包,那么…

代碼隨想錄第14天| 翻轉、對稱與深度

226.翻轉二叉樹 (優先掌握遞歸) 題目鏈接/文章講解/視頻講解:翻轉二叉樹 交換的是指針,而不是數值,如果用數值做交換,需要交換的節點下面無法很好的操作。 使用遞歸來實現,但要提前清除是什么順…

DNS-Windows上使用DNS

DNS-Windows上使用DNS一、查看與修改DNS配置1.1、查看當前DNS服務器設置1.2、臨時修改 DNS 服務器(命令行)二、DNS緩存相關操作2.1、查看DNS緩存內容2.2、 刷新 DNS 緩存(清除過期記錄)三、測試域名解析(nslookup 工具…

3dsMax 2026 .NET Core 8 轉型下的Maxscript腳本開發:動態編譯模塊的重構策略與兼容性升級路徑

3ds Max 長期以來一直提供出色的 .NET 集成,使 Maxscript 能夠無縫利用任何 .NET 庫的強大功能。部分開發者在工具中廣泛使用了 .NET 功能。 之前,3ds Max 依賴于 .NET Framework 4.8 并且最近更新到了 4.8.1,用于 2025 版本的發布。然而,隨著 3ds Max 2026 的推出,Autod…

golang 做webrtc開發核心

在Golang中進行WebRTC開發,核心在于理解WebRTC協議的工作原理以及如何利用Go生態中的庫來實現關鍵功能。以下是Golang WebRTC開發的核心要點: WebRTC基礎概念 了解ICE(Interactive Connectivity Establishment)協議用于NAT穿越掌握…

RabbitMQ 異步化抗洪實戰

說明:本文僅展示架構思路與安全片段,所有敏感字段已用占位符;不含可直接復刻的生產細節。數據與接口均為演示/虛擬。0. 背景與目標長耗時/不確定接口(如對接第三方機器人平臺)的同步阻塞,容易造成請求堆積與…

接口返回 2 萬條數據,easy-trans導致多了20s耗時排查過程

內網訪問排版核料詳情功能,用戶反饋要等十幾秒排查 sql:sql 比較簡單排查內存計算:arthus trace 類名 方法名 總耗時2s排查頁面渲染是否緩慢:F12 查看接口 等待服務器響應 20s 下載時間 30s, 故不考慮渲染問題排查請求響應日志打…

AIGC入門,手搓大模型客戶端與MCP交互

概述 在現代應用開發中,將大語言模型(LLM)與專用工具服務相結合,可以構建出既能理解自然語言,又能準確執行專業任務的智能代理。本文介紹一個基于 MCP(Model Context Protocol)協議和 Ollama 本…

深度學習:從預備知識到未來展望

在當今數字化時代,深度學習正以前所未有的速度改變著我們的生活和工作方式。從智能語音助手到自動駕駛汽車,從精準醫療到個性化推薦系統,深度學習的應用無處不在。本文將從深度學習的預備知識入手,探討其發展歷程、關鍵技術和未來…

軟考高級系統架構設計師之構件與中間件技術篇

一、構件的定義 定義1:軟件構件是一種組裝單元,它具有規范的接口規約和顯式的語境依賴。軟件構件可以被獨立地部署并由第三方任意地組裝。 定義2:構件是某系統中有價值的、幾乎獨立的并可替換的一個部分,它在良好定義的體系結構語境內滿足某清晰的功能。…

Node.js 文件上傳中文文件名亂碼問題,為什么只有Node會有亂碼問題,其他后端框架少見?

問題現象當用戶上傳包含中文字符的文件時,在服務器端獲取到的文件名可能變成類似 ????.txt 這樣的亂碼,而不是預期的中文文件名。為什么只有Node會亂碼?很多后端框架(如 Java Spring Boot、Python Django、PHP Laravel&#x…

學習英語音標 (從漢語角度看英語音標發音差異)

僅供參考, 跟著教學視頻看不懂時再來看以下引導 以下只寫容易出錯的音標 發音視頻: https://www.jiwake.com/yinbiaofayin/ 音標規則單詞??類似漢語e, 餓~urge?類似漢語e, 餓go??類似漢語o, 哦~walk?類似漢語o, 哦wash?/i?/的短語, 不止發聲短,舌頭不用隆起it?類似漢…

論文筆記(九十一)GWM: Towards Scalable Gaussian World Models for Robotic Manipulation

GWM: Towards Scalable Gaussian World Models for Robotic Manipulation文章概括摘要1. 引言2. 相關工作3. 高斯世界模型(Gaussian World Model)3.1. 世界狀態編碼(World State Encoding)3.2. 基于擴散的動態建模(Dif…

apache phoenix sql 命令大全詳解

這是一份非常詳細的 Apache Phoenix SQL 命令大全和詳解。Phoenix 作為 HBase 上的 SQL 層,其語法大部分與標準 SQL 兼容,但也有許多針對 HBase 的特性擴展。核心概念 在開始之前,請記住 Phoenix 的兩個核心概念: 主鍵&#xff08…

【代碼講解】SO-ARM100 雙場景演示:手柄驅動 Mujoco 仿真 + 實機控制

視頻講解: 【代碼講解】SO-ARM100 雙場景演示:手柄驅動 Mujoco 仿真 實機控制今天介紹下使用使用北通手柄通過控制 Mujoco 中的 SO-ARM100 機械臂,然后將關節數據通過 zmq 通信轉發控制實際機械臂。 本期中會涉及如下點,需要注意…

「數據獲取」《中國教育經費統計年鑒》(1997-2024)

01、數據簡介《中國教育經費統計年鑒》作為我國教育經費領域的核心統計典籍,全面系統地呈現了全國各級各類教育經費的來源構成、分配流向與使用成效。其統計范圍覆蓋學前教育、基礎教育、中等職業教育、高等教育及特殊教育等全學段,數據維度涵蓋財政性教…

使用 Logspout 收集所有容器的

1.將所有容器的輸出路由到遠程 rsyslog 服務器1.修改 rsyslog 配置文件/etc/rsyslog.conf, 從中找到 “# Provides UDP sysilog recepion"語句。并將該處的以下兩行配置代碼行首的“#”字符刪除(取消注釋)[roothost1 ~]# vi /etc/rsyslog.conf [roo…

【智能化解決方案】基于多目標優化檢索增強生成的智能行程規劃方案

📝 基于多目標優化的智能行程規劃方案 1 用戶需求分析與矩陣構建 1.1 核心用戶信息提取 根據用戶提供的年齡、出發地、目的地、出行時間等基本信息,我們首先構建一個用戶特征向量: U {Age, Origin, Destination, TravelDate, Duration, Budg…

軟件研發的演變

軟件研發從一門手工作坊式的藝術,逐步演進為一門系統化、工程化、智能化的現代學科。其發展歷程不僅體現了技術的飛躍,更反映了方法論、協作模式和思維方式的深刻變革。一、發展演變歷程軟件研發的演變可以大致劃分為以下幾個階段:1. 軟件作坊…

「日拱一碼」091 機器學習——集成學習

目錄 集成學習介紹 1. 核心思想 2. 為什么有效? 3. 主要流派與方法 A. 并行方法:Bagging (Bootstrap Aggregating) B. 串行方法:Boosting C. 堆疊法:Stacking 代碼示例 Bagging 的代表 —— 隨機森林 (Random Forest) 集成…