Python 網絡編程 -- WebSocket編程

作者主要是為了用python構建實時網絡通信程序。

概念性的東西越簡單越好理解,因此,下面我從晚上摘抄的概念 + 我的理解。

什么是網絡通信?

更確切地說,網絡通信是兩臺計算機上的兩個進程之間的通信。比如,瀏覽器進程和新浪服務器上的某個Web服務進程在通信,而QQ進程是和騰訊的某個服務器上的某個進程在通信。

而網絡編程就是針對網絡通信的編程。

1.網絡編程基礎

1.1 基本概念與協議

TCP/IP協議棧

網絡編程的基礎是 理解數據在網絡中的傳輸過程,這通常通過OSI模型和TCP/IP協議棧進行解釋。而TCP/IP協議棧則是實際應用中更為廣泛的模型,包含物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層和應用層

計算機為了聯網,需要規定通信協議,一開始是不統一的,相互不同協議之間的計算機交互是困難的。因此,就出現了互聯網協議簇,任何網絡只要遵守這個協議,就可以連入互聯網。

互聯網協議,包括上百種協議,最重要的當屬TCP/IP協議,因此,大家把互聯網協議簡稱TCP/IP協議。

通信的時候,雙方必須知道對方的標識,好比發郵件必須知道對方的郵件地址。互聯網上每個計算機的唯一標識就是IP地址,類似123.123.123.123。如果一臺計算機同時接入到兩個或更多的網絡,比如路由器,它就會有兩個或多個IP地址,所以,IP地址對應的實際上是計算機的網絡接口,通常是網卡。

IP協議負責把數據從一臺計算機通過網絡發送到另一臺計算機。數據被分割成一小塊一小塊,然后通過IP包發送出去。由于互聯網鏈路復雜,兩臺計算機之間經常有多條線路,因此,路由器就負責決定如何把一個IP包轉發出去。IP包的特點是按塊發送,途徑多個路由,但不保證能到達,也不保證順序到達。

TCP協議則是建立在IP協議之上的。TCP協議負責在兩臺計算機之間建立可靠連接,保證數據包按順序到達。TCP協議會通過握手建立連接,然后,對每個IP包編號,確保對方按順序收到,如果包丟掉了,就自動重發。

許多常用的更高級的協議都是建立在TCP協議基礎上的,比如用于瀏覽器的HTTP協議、發送郵件的SMTP協議等。

一個TCP報文除了包含要傳輸的數據外,還包含源IP地址和目標IP地址,源端口和目標端口。

端口有什么作用?在兩臺計算機通信時,只發IP地址是不夠的,因為同一臺計算機上跑著多個網絡程序。一個TCP報文來了之后,到底是交給瀏覽器還是QQ,就需要端口號來區分。每個網絡程序都向操作系統申請唯一的端口號,這樣,兩個進程在兩臺計算機之間建立網絡連接就需要各自的IP地址和各自的端口號。

一個進程也可能同時與多個計算機建立鏈接,因此它會申請很多端口。

TCP

TCP (Transmission Control Protocol) 是面向連接的、提供端到端可靠的數據流(flow of data)。TCP 提供超時重發,丟棄重復數據,檢驗數據,流量控制等功能,保證數據能從一端傳到另一端。

“面向連接”就是在正式通信前必須要與對方建立起連接。這一過程與打電話很相似,先撥號振鈴,等待對方摘機說“喂”,然后才說明是誰。

端到端的數據流,建立在IP協議之上,提供超時重發、重復數據校驗、流量控制燈基本功能。

保證數據能從一端到另一端。

三次握手

TCP 是基于連接的協議,也就是說,在正式收發數據前,必須和對方建立可靠的連接。一個 TCP 連接必須要經過三次“握手”才能建立起來,簡單的講就是:

  1. 主機 A 向主機 B 發出連接請求數據包:“我想給你發數據,可以嗎?”;
  2. 主機 B 向主機 A 發送同意連接和要求同步(同步就是兩臺主機一個在發送,一個在接收,協調工作)的數據包:“可以,你來吧”;
  3. 主機 A 再發出一個數據包確認主機 B 的要求同步:“好的,我來也,你接著吧!”

三次“握手”的目的是使數據包的發送和接收同步,經過三次“對話”之后,主機 A 才向主機 B 正式發送數據。

A和B要通過 TCP通信的流程:

A 連接B,B被連接允許A連接,A接受到響應確認連接B。 -> A和B可以通信了。

UDP

UDP (User Datagram Protocol) 面向無連接的,主機發送獨立的數據報(datagram)給其他主機,不保證數據到達。由于 UDP 在傳輸數據報前不用在客戶和服務器之間建立一個連接,且沒有超時重發等機制,故而傳輸速度很快。

而無連接是一開始就發送信息(嚴格說來,這是沒有開始、結束的),只是一次性的傳遞,是先不需要接受方的響應,因而在一定程度上也無法保證信息傳遞的可靠性了,就像寫信一樣,我們只是將信寄出去,卻不能保證收信人一定可以收到。

通信時,可以不用與目標主機建立連接,就能發送數據。

A和B通信,直接發送就可以,不用管對方是否? "可連接"。

TCP 是面向連接的,有比較高的可靠性, 一些要求比較高的服務一般使用這個協議,如FTP、Telnet、SMTP、HTTP、POP3 等,而 UDP 是面向無連接的,使用這個協議的常見服務有 DNS、SNMP、QQ 等。對于 QQ 必須另外說明一下,QQ2003 以前是只使用UDP協議的,其服務器使用8000端口,偵聽是否有信息傳來,客戶端使用 4000 端口,向外發送信息(這也就不難理解在一般的顯IP的QQ版本中顯示好友的IP地址信息中端口常為4000或其后續端口的原因了),即QQ程序既接受服務又提供服務,在以后的 QQ 版本中也支持使用 TCP 協議了。

端口

一般來說,一臺計算機具有單個物理連接到網絡。數據通過這個連接去往特定的計算機。然而,該數據可以被用于在計算機上運行的不同應用。那么,計算機知道哪個應用程序轉發數據?通過使用端口。

在互聯網上傳輸的數據是通過計算機的標識和端口來定位的。計算機的標識是 32-bit 的 IP 地址。端口由一個 16-bit 的數字。

在諸如面向連接的通信如 TCP,服務器應用將套接字綁定到一個特定端口號。這是向系統注冊服務用來接受該端口的數據。然后,客戶端可以在與服務器在服務器端口會合,如下圖所示:

網絡基礎 - 圖2

TCP 和 UDP 協議使用的端口來將接收到的數據映射到一個計算機上運行的進程。

在基于數據報的通信,如 UDP,數據報包中包含它的目的地的端口號,然后 UDP 將數據包路由到相應的應用程序,如本圖所示的端口號:

網絡基礎 - 圖3

端口號取值范圍是從 0 到 65535 (16-bit 長度),其中范圍從 0 到 1023 是受限的,它們是被知名的服務所保留使用,例如 HTTP (端口是 80)和 FTP (端口是20、21)等系統服務。這些端口被稱為眾所周知的端口(well-known ports)。您的應用程序不應該試圖綁定到他們。

嗯 ...,網絡通信具體來講,是兩個進程之間的通信,很顯然我們只要目標主機的IP是沒法跟對方通信的,因此我們還必須知道目標進程運行占用的端口,通過 ip + port來與其通信。

2. Socket

Socket(套接字):是在網絡上運行兩個程序之間的雙向通信鏈路的一個端點socket綁定到一個端口號,使得 TCP 層可以標識數據最終要被發送到哪個應用程序

正常情況下,一臺服務器在特定計算機上運行,??并具有被綁定到特定端口號的 socket。服務器只是等待,并監聽用于客戶發起的連接請求的 socket 。

在客戶端:客戶端知道服務器所運行的主機名稱以及服務器正在偵聽的端口號。建立連接請求時,客戶端嘗試與主機服務器和端口會合。客戶端也需要在連接中將自己綁定到本地端口以便于給服務器做識別。本地端口號通常是由系統分配的。

Socket - 圖1

如果一切順利的話,服務器接受連接。一旦接受,服務器獲取綁定到相同的本地端口的新 socket ,并且還具有其遠程端點設定為客戶端的地址和端口。它需要一個新的socket,以便它可以繼續監聽原來用于客戶端連接請求的 socket 。

Socket - 圖2

在客戶端,如果連接被接受,則成功地創建一個套接字和客戶端可以使用該 socket 與服務器進行通信。

客戶機和服務器現在可以通過 socket 寫入或讀取來交互了。

端點是IP地址和端口號的組合。每個 TCP 連接可以通過它的兩個端點被唯一標識。這樣,你的主機和服務器之間可以有多個連接。

Socket是對互聯網通信協議(如TCP/IP)的封裝和應用,它提供了一個調用接口(API),通過這個接口我們可以使用這些協議棧來與目標計算機進行通信。

在具體的編程語言中,針對不同的通信協議會有不同的Socket實現。當你需要與目標計算機進行基于某個協議的通信時,你可以調用相應協議的Socket實現。這些Socket實現會根據協議的要求進行數據的封裝和解封裝,以便你能夠與目標計算機進行通信。

因此,通過創建針對特定協議的Socket實現,你就可以使用Socket進行基于該協議的通信了。

具體舉一下例子:

如果抖音有一個通信協議,并且針對Java提供了一個具體的SDK,那么這個SDK中應該包含了一個Socket的實現,用于與抖音服務器進行通信。

當你創建這個Socket時,你可以使用SDK提供的API來與抖音服務器建立連接、發送和接收數據。SDK會根據抖音的通信協議對數據進行封裝和解封裝,以便你能夠與抖音服務器進行通信。

因此,通過創建這個Socket,你就可以使用SDK提供的API與抖音服務器進行通信了。

服務器指一個管理資源并為用戶提供服務的計算機軟件,通常分為文件服務器、數據庫服務器和應用程序服務器。嚴格來說,服務器本身就是計算機硬件,并在其中運行的管理軟件的一種管理資源,就如同電腦。按硬件還會分塔式服務器、卡片機、小型機。是一個大的概念,任何一臺電腦安裝了軟件的服務器端就可以叫服務器。

2.Python網絡編程

Socket

python提供了內置socket庫,從而能夠進行網路通信。下面我們直接展示一個案例。

下面簡單利用了sockert庫,來建立一個服務器,并且建立了一個客戶端,去訪問服務器并進行數據交互。

來源于菜鳥編程:?Python 網絡編程 | 菜鳥教程 (runoob.com)

Server.py

import socket
if __name__ == '__main__':# 建立一個服務端server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind(('localhost', 6999))  # 綁定要監聽的端口server.listen(5)  # 開始監聽 表示可以使用五個鏈接排隊while True:  # conn就是客戶端鏈接過來而在服務端為期生成的一個鏈接實例conn, addr = server.accept()  # 等待鏈接,多個鏈接的時候就會出現問題,其實返回了兩個值print(conn, addr)while True:try:data = conn.recv(1024)  # 接收數據print('recive:', data.decode())  # 打印接收到的數據conn.send(data.upper())  # 然后再發送數據except ConnectionResetError as e:print('關閉了正在占線的鏈接!')breakconn.close()

client.py

import socket
if __name__ == '__main__':client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 聲明socket類型,同時生成鏈接對象client.connect(('localhost', 6999))  # 建立一個鏈接,連接到本地的6969端口while True:# addr = client.accept()# print '連接地址:', addrmsg = '歡迎訪問菜鳥教程!'  # strip默認取出字符串的頭尾空格client.send(msg.encode('utf-8'))  # 發送一條信息 python3 只接收btye流data = client.recv(1024)  # 接收一個信息,并指定接收的大小 為1024字節print('recv:', data.decode())  # 輸出我接收的信息client.close()  # 關閉這個鏈接

WebSocket

?PS:以下全引用于HTML 菜鳥編程:?HTML5 WebSocket | 菜鳥教程 (runoob.com)

WebSocket 是 HTML5 開始提供的一種在單個 TCP 連接上進行全雙工通訊的協議。

WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據。在 WebSocket API 中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,并進行雙向數據傳輸。

在 WebSocket API 中,瀏覽器和服務器只需要做一個握手的動作,然后,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。

現在,很多網站為了實現推送技術,所用的技術都是 Ajax 輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,然后由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器需要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費很多的帶寬等資源。

HTML5 定義的 WebSocket 協議,能更好的節省服務器資源和帶寬,并且能夠更實時地進行通訊。

瀏覽器通過 JavaScript 向服務器發出建立 WebSocket 連接的請求,連接建立以后,客戶端和服務器端就可以通過 TCP 連接直接交換數據。

當你獲取 Web Socket 連接后,你可以通過?send()?方法來向服務器發送數據,并通過?onmessage?事件來接收服務器返回的數據。

以下 API 用于創建 WebSocket 對象。

我們可以看出,websocket協議是基于tcp協議的全雙工通信協議。

它,允許服務端主動向客戶端推送數據。而且,只需要一次握手,就可建立一次長連接

與傳統?AJAX輪訓方法實現推送技術相比,發送請求的次數減少,(數據每一次更新,就代表一次ajax的請求和響應,這是相對比較浪費帶寬資源的,通過websocket,客戶端和服務端可以建立一次長連接完成數據的交互。)

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

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

相關文章

GM DC Monitor如何實現TCP端口狀態監控-操作分享

本節講解如何通過現有指標提取監控腳本制作自定義的TCP端口監控指標 一、功能介紹 通過提取已有的監控指標的監控命令,來自定義TCP端口的監控指標。 二、配置端口監控 1)定位監控腳本 確定腳本及參數如下: check_protocol_tcp.pl --plug…

LabVIEW與Modbus/TCP溫濕度監控系統

基于LabVIEW 開發平臺與 Modbus/TCP 通信協議,設計一套適用于實驗室環境的溫濕度數據采集監控系統。通過上位機與高精度溫濕度采集設備的遠程通信,實現多設備溫濕度數據的實時采集、存儲、分析及報警功能,解決傳統人工采集效率低、環境適應性…

Ntfs!ReadIndexBuffer函數分析之nt!CcGetVirtualAddress函數之nt!CcGetVacbMiss

第一部分: NtfsMapStream( IrpContext, Scb, LlBytesFromIndexBlocks( IndexBlock, Scb->ScbType.Index.IndexBlockByteShift ), Scb->ScbType.Index.BytesPerIndexBuffer, &am…

vite+vue3項目中,單個組件中使用 @use報錯

報錯信息: [plugin:vite:css] [sass] use rules must be written before any other rules.use 官方說明 注意事項: https://sass-lang.com/documentation/at-rules/use/ 樣式表中的 use 規則必須位于所有其他規則(除 forward 外&#xff0…

基于VMD-LSTM融合方法的F10.7指數預報

F10.7 Daily Forecast Using LSTM Combined With VMD Method ??F10.7?? solar radiation flux is a well-known parameter that is closely linked to ??solar activity??, serving as a key index for measuring the level of solar activity. In this study, the ??…

React 新項目

使用git bash 創建一個新項目 建議一開始就創建TS項目 原因在Webpack中改配置麻煩 編譯方法:ts compiler 另一種 bable 最好都配置 $ create-react-app cloundmusic --template typescript 早期react項目 yarn 居多 目前npm包管理居多 目前pnpm不通用 icon 在public文件夾中…

2025年- H65-Lc173--347.前k個高頻元素(小根堆,堆頂元素是當前堆元素里面最小的)--Java版

1.題目描述 2.思路 (1)這里定義了一個小根堆(最小堆),根據元素的頻率從小到大排序。小根堆原理:堆頂是最小值,每次插入或刪除操作會保持堆的有序結構(常用二叉堆實現)。 …

VR/AR 顯示瓶頸將破!鐵電液晶技術迎來關鍵突破

在 VR/AR 設備逐漸走進大眾生活的今天,顯示效果卻始終是制約其發展的一大痛點。紗窗效應、畫面拖影、眩暈感…… 傳統液晶技術的瓶頸讓用戶體驗大打折扣。不過,隨著鐵電液晶技術的重大突破,這一局面有望得到徹底改變。 一、傳統液晶技術瓶頸…

【bug】Error: /undefinedfilename in (/tmp/ocrmypdf.io.9xfn1e3b/origin.pdf)

在使用ocrmypdf的時候,需要Ghostscript9.55及以上的版本,但是ubuntu自帶為9.50 然后使用ocrmypdf報錯了 sudo apt update sudo apt install ghostscript gs --version 9.50 #版本不夠安裝的版本為9.50不夠,因此去官網https://ghostscript.c…

【TinyWebServer】線程同步封裝

目錄 POSIX信號量 int sem_init(sem_t* sem,int pshared,unsingned int value); int sem_destroy(sem_t* sem); int sem_wait(sem_t* sem); int sem_post(sem_t* sem); 互斥量 條件變量 為了對多線程程序實現同步問題,可以用信號量POSIX信號量、互斥量、條件變…

打造高效多模態RAG系統:原理與評測方法詳解

引言 隨著信息檢索與生成式AI的深度融合,檢索增強生成(RAG, Retrieval-Augmented Generation) 已成為AI領域的重要技術方向。傳統RAG系統主要依賴文本數據,但真實世界中的信息往往包含圖像、表格等多模態內容。多模態RAG&#xf…

Unity安卓平臺開發,啟動app并傳參

using UnityEngine; using System;public class IntentReceiver : MonoBehaviour {public bool isVR1;void Start(){Debug.LogError("app1111111111111111111111111");if (isVR1){LaunchAnotherApp("com.HappyMaster.DaKongJianVR2");}else{// 檢查是否有傳…

云計算 Linux Rocky day05【rpm、yum、history、date、du、zip、ln】

云計算 Linux Rocky day05【rpm、yum、history、date、du、zip、ln】 目錄 云計算 Linux Rocky day05【rpm、yum、history、date、du、zip、ln】1.RPM包的一般安裝位置2.軟件名和軟件包名3.查詢軟件信息4.查詢軟件包5.導入紅帽簽名信息,解決查詢軟件包信息報錯6.利用…

【圖像處理3D】:點云圖是怎么生成的

點云圖是怎么生成的 **一、點云數據的采集方式****1. 激光雷達(LiDAR)****2. 結構光(Structured Light)****3. 雙目視覺(Stereo Vision)****4. 飛行時間相機(ToF Camera)****5. 其他…

javaweb -html -CSS

HTML是一種超文本標記語言 超文本&#xff1a;超過了文本的限制&#xff0c;比普通文本更強大&#xff0c;除了文字信息&#xff0c;還可以定義圖片、音頻、視頻等內容。 標記語言&#xff1a;由標簽"<標簽名>"構成的語言。 CSS:層疊樣式表&#xff0c;用于…

pyinstaller 安裝 ubuntu

安裝命令 pip install pyinstaller 讀取安裝路徑 ? ~ find ~/.local/ -name pyinstaller/home/XXX/.local/bin/pyinstaller 路徑配置 vi ~/.zshrc 添加到文件最后 export PATH"$PATH:/home/XXX/.local/bin/" 查看版本號 ? ~ source ~/.zshrc? ~ pyi…

【前端】掌握HTML/CSS寬高調整:抓住問題根源,掌握黃金法則

一、寬高控制的「黃金法則」 問題根源&#xff1a;為什么設置了寬高沒效果&#xff1f; <!-- 典型失敗案例 --> <style>.problem-box {width: 200px;height: 100px;padding: 20px; /* 實際變成240x140px&#xff01; */border: 5px solid red; /* 最終250x150px&…

LuaJIT2.1 和 Lua5.4.8 性能對比

說明 最近在學習 LuaJIT&#xff0c;想看看把它接入到項目中使用&#xff0c;會提高多大的性能。 今天抽時間&#xff0c;簡單地測試了一下 LuaJIT 2.2 和 Lua5.4.8 的性能。 測試平臺&#xff1a; 系統&#xff1a;Windows 10 WSLCPU&#xff1a;Intel Core? i7-8700 CPU…

Arduino學習-按鍵燈

哎&#xff0c;別笑&#xff0c;總比刷抖音強點吧 1、效果 2、代碼 const int buttonPin2; const int ledPin13;int buttonState0;void setup() {// put your setup code here, to run once:pinMode(buttonPin,INPUT);pinMode(ledPin,OUTPUT); }void loop() {// put your mai…

強化學習魚書(10)——更多深度強化學習的算法

&#xff1a;是否使用環境模型&#xff08;狀態遷移函數P(s’|s,a)和獎 勵函數r(s&#xff0c;a&#xff0c;V)&#xff09;。不使用環境模型的方法叫作無模型&#xff08;model-free&#xff09;的方法&#xff0c;使用環境模型的方法叫作有模型&#xff08;model-based&#…