天天看點

python socket_【技術分享】Python3(14) Python 網絡程式設計

本系列主要學習Python的基本使用和文法知識,後續可能會圍繞着AI學習展開。

Python3 (1) Python語言的簡介

Python3 (2) Python文法基礎

Python3 (3) Python函數

Python3 (4) Python進階特性

Python3 (5) Python 函數式程式設計

Python3 (6) Python 子產品

Python3 (7) Python 面向對象程式設計

Python3 (8) Python 面向對象進階程式設計

Python3 (9) Python 錯誤、調試和測試

Python3 (10) Python IO程式設計

Python3 (11) Python 程序和線程

Python3 (12) Python 常用内模組化塊

Python3 (13) Python 常用第三方子產品

Python3 (14) Python 網絡程式設計

首先說一下最近要忙别的事情,Python 學習可能會中斷一小段時間,不過基礎篇已經差不多學習完了,再次開始學習的時候主要以項目的形式學習,穿插剩餘的知識點,Python (13) 常見的第三方子產品 還沒完成,之後會寫完發出,今天主要是學習 Python 的網絡程式設計,順便複習一下網絡程式設計這塊的知識。

網絡程式設計

網絡程式設計就是如何在程式中實作兩台計算機的通信,現在的應用基本上都需要網絡,單機應用基本上很少,是以網絡程式設計是一個非常重要又非常基礎的知識點,并且網絡程式設計對所有開發語言都是一樣的,Python也不例外。用Python進行網絡程式設計,就是在Python程式本身這個程序内,連接配接别的伺服器程序的通信端口進行通信。

TCP/IP簡介

從網際網路說起,之是以現在網際網路無處不在,就是因為計算機網絡在發展過程中形成了一套全球通用的協定,網際網路協定簇(Internet Protocol Suite)就是通用協定标準。因為網際網路協定包含了上百種協定标準,但是最重要的兩個協定是TCP和IP協定,是以,大家把網際網路的協定簡稱TCP/IP協定。
  • IP位址:通信的時候,雙方必須知道對方的辨別,網際網路上每個計算機的唯一辨別就是IP位址,類似123.123.123.123。如果是路由器,它就會有兩個或多個IP位址,是以,IP位址對應的實際上是計算機的網絡接口,通常是網卡,IP 協定位于 TCP/IP 協定的第三層——網絡層。與傳輸層協定相比,網絡層的責任是提供點到點(hop by hop)的服務,而傳輸層(TCP/UDP)則提供端到端(end to end)的服務。。
  • IP協定:負責把資料從一台計算機通過網絡發送到另一台計算機。資料被分割成一小塊一小塊,然後通過IP包發送出去。由于網際網路鍊路複雜,兩台計算機之間經常有多條線路,是以,路由器就負責決定如何把一個IP包轉發出去。IP包的特點是按塊發送,途徑多個路由,但不保證能到達,也不保證順序到達。
  • TCP協定:TCP協定則是建立在IP協定之上的。TCP協定負責在兩台計算機之間建立可靠連接配接,保證資料包按順序到達。TCP協定會通過握手建立連接配接,然後,對每個IP包編号,確定對方按順序收到,如果包丢掉了,就自動重發。比如用于浏覽器的HTTP協定、發送郵件的SMTP協定都是在TCP 協定基礎上定義的更進階的協定。一個TCP封包除了包含要傳輸的資料外,還包含源IP位址和目标IP位址,源端口和目标端口。
  • Socket:Socket 是對 TCP/IP 協定族的一種封裝,是應用層與TCP/IP協定族通信的中間軟體抽象層。從設計模式的角度看來,Socket其實就是一個門面模式,它把複雜的TCP/IP協定族隐藏在Socket接口後面,對使用者來說,一組簡單的接口就是全部,讓Socket去組織資料,以符合指定的協定;Socket 還可以認為是一種網絡間不同計算機上的程序通信的一種方法,利用三元組(ip位址,協定,端口)就可以唯一辨別網絡中的程序,網絡中的程序通信可以利用這個标志與其它程序進行互動;Socket 起源于 Unix ,Unix/Linux 基本哲學之一就是“一切皆檔案”,都可以用“打開(open) –> 讀寫(write/read) –> 關閉(close)”模式來進行操作。是以 Socket 也被處理為一種特殊的檔案。

TCP程式設計

Socket表示“打開了一個網絡連結”,而打開一個Socket需要知道目标計算機的IP位址和端口号,再指定協定類型即可。建立TCP連接配接時,主動發起連接配接的叫用戶端,被動響應連接配接的叫伺服器。
  • 用戶端:

輸出結果:

在目錄下生成 sina.html檔案,打開就是新浪首頁。每一步操作都備注了,可以看出用戶端要發起一個網絡請求需要 5 步,建立 socket 時需要指定是那種協定,SOCK_STREAM指定使用面向流的TCP協定。接受完資料後要記得關閉 socket。

  • 服務端:

輸出結果:

以上完成了一個用戶端使用TCP協定送出請求,伺服器接收處理,傳回用戶端資訊的完整過程。以下是TCP程式設計的特點:

  • TCP 提供一種面向連接配接的、可靠的位元組流服務
  • 在一個 TCP 連接配接中,僅有兩方進行彼此通信。廣播和多點傳播不能用于 TCP
  • TCP 使用校驗和,确認和重傳機制來保證可靠傳輸
  • TCP 給資料分節進行排序,并使用累積确認保證資料的順序不變和非重複
  • TCP 使用滑動視窗機制來實作流量控制,通過動态改變視窗的大小進行擁塞控制

    注意:TCP 并不能保證資料一定會被對方接收到,因為這是不可能的。TCP 能夠做到的是,如果有可能,就把資料遞送到接收方,否則就(通過放棄重傳并且中斷連接配接這一手段)通知使用者。是以準确說 TCP 也不是 100% 可靠的協定,它所能提供的是資料的可靠遞送或故障的可靠通知。

UDP程式設計

TCP是建立可靠連接配接,并且通信雙方都可以以流的形式發送資料。相對TCP,UDP則是面向無連接配接的協定。使用UDP協定時,不需要建立連接配接,隻需要知道對方的IP位址和端口号,就可以直接發資料包。但是,能不能到達就不知道了。
  • 缺點:UDP傳輸資料不可靠
  • 優點:和TCP比,速度快,對于不要求可靠到達的資料,就可以使用UDP協定

直接上代碼:

輸出結果:

以上就是UDP協定的使用,UDP的使用與TCP類似,但是不需要建立連接配接。此外,伺服器綁定UDP端口和TCP端口互不沖突,也就是說,UDP的9999端口與TCP的9999端口可以各自綁定。以下是幾個UDP程式設計的特點:

  • UDP 缺乏可靠性。UDP 本身不提供确認,序列号,逾時重傳等機制。UDP 資料報可能在網絡中被複制,被重新排序。即 UDP 不保證資料報會到達其最終目的地,也不保證各個資料報的先後順序,也不保證每個資料報隻到達一次
  • UDP 資料報是有長度的。每個 UDP 資料報都有長度,如果一個資料報正确地到達目的地,那麼該資料報的長度将随資料一起傳遞給接收方。而 TCP 是一個位元組流協定,沒有任何(協定上的)記錄邊界。
  • UDP 是無連接配接的。UDP 客戶和伺服器之前不必存在長期的關系。UDP 發送資料報之前也不需要經過握手建立連接配接的過程。
  • UDP 支援多點傳播和廣播。

TCP三向交握與四次揮手機制

所謂三次握手(Three-way Handshake),是指建立一個 TCP 連接配接時,需要用戶端和伺服器總共發送3個包。

三次握手的目的是連接配接伺服器指定端口,建立 TCP 連接配接,并同步連接配接雙方的序列号和确認号,交換 TCP 視窗大小資訊。在 socket 程式設計中,用戶端執行 connect() 時。将觸發三次握手。

第一次握手(SYN=1, seq=x):

用戶端發送一個 TCP 的 SYN 标志位置1的包,指明用戶端打算連接配接的伺服器的端口,以及初始序号 X,儲存在標頭的序列号(Sequence Number)字段裡。

發送完畢後,用戶端進入 SYN_SEND 狀态。

第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):

伺服器發回确認包(ACK)應答。即 SYN 标志位和 ACK 标志位均為1。伺服器端選擇自己 ISN 序列号,放到 Seq 域裡,同時将确認序号(Acknowledgement Number)設定為客戶的 ISN 加1,即X+1。發送完畢後,伺服器端進入 SYN_RCVD 狀态。

第三次握手(ACK=1,ACKnum=y+1)

用戶端再次發送确認包(ACK),SYN 标志位為0,ACK 标志位為1,并且把伺服器發來 ACK 的序号字段+1,放在确定字段中發送給對方,并且在資料段放寫ISN的+1

發送完畢後,用戶端進入 ESTABLISHED 狀态,當伺服器端接收到這個包時,也進入 ESTABLISHED 狀态,TCP 握手結束。

三次握手的過程的示意圖如下:

本系列主要學習Python的基本使用和文法知識,後續可能會圍繞着AI學習展開。

Python3 (1) Python語言的簡介

Python3 (2) Python文法基礎

Python3 (3) Python函數

Python3 (4) Python進階特性

Python3 (5) Python 函數式程式設計

Python3 (6) Python 子產品

Python3 (7) Python 面向對象程式設計

Python3 (8) Python 面向對象進階程式設計

Python3 (9) Python 錯誤、調試和測試

Python3 (10) Python IO程式設計

Python3 (11) Python 程序和線程

Python3 (12) Python 常用内模組化塊

Python3 (13) Python 常用第三方子產品

Python3 (14) Python 網絡程式設計

首先說一下最近要忙别的事情,Python 學習可能會中斷一小段時間,不過基礎篇已經差不多學習完了,再次開始學習的時候主要以項目的形式學習,穿插剩餘的知識點,Python (13) 常見的第三方子產品 還沒完成,之後會寫完發出,今天主要是學習 Python 的網絡程式設計,順便複習一下網絡程式設計這塊的知識。

網絡程式設計

網絡程式設計就是如何在程式中實作兩台計算機的通信,現在的應用基本上都需要網絡,單機應用基本上很少,是以網絡程式設計是一個非常重要又非常基礎的知識點,并且網絡程式設計對所有開發語言都是一樣的,Python也不例外。用Python進行網絡程式設計,就是在Python程式本身這個程序内,連接配接别的伺服器程序的通信端口進行通信。

TCP/IP簡介

從網際網路說起,之是以現在網際網路無處不在,就是因為計算機網絡在發展過程中形成了一套全球通用的協定,網際網路協定簇(Internet Protocol Suite)就是通用協定标準。因為網際網路協定包含了上百種協定标準,但是最重要的兩個協定是TCP和IP協定,是以,大家把網際網路的協定簡稱TCP/IP協定。
  • IP位址:通信的時候,雙方必須知道對方的辨別,網際網路上每個計算機的唯一辨別就是IP位址,類似123.123.123.123。如果是路由器,它就會有兩個或多個IP位址,是以,IP位址對應的實際上是計算機的網絡接口,通常是網卡,IP 協定位于 TCP/IP 協定的第三層——網絡層。與傳輸層協定相比,網絡層的責任是提供點到點(hop by hop)的服務,而傳輸層(TCP/UDP)則提供端到端(end to end)的服務。。
  • IP協定:負責把資料從一台計算機通過網絡發送到另一台計算機。資料被分割成一小塊一小塊,然後通過IP包發送出去。由于網際網路鍊路複雜,兩台計算機之間經常有多條線路,是以,路由器就負責決定如何把一個IP包轉發出去。IP包的特點是按塊發送,途徑多個路由,但不保證能到達,也不保證順序到達。
  • TCP協定:TCP協定則是建立在IP協定之上的。TCP協定負責在兩台計算機之間建立可靠連接配接,保證資料包按順序到達。TCP協定會通過握手建立連接配接,然後,對每個IP包編号,確定對方按順序收到,如果包丢掉了,就自動重發。比如用于浏覽器的HTTP協定、發送郵件的SMTP協定都是在TCP 協定基礎上定義的更進階的協定。一個TCP封包除了包含要傳輸的資料外,還包含源IP位址和目标IP位址,源端口和目标端口。
  • Socket:Socket 是對 TCP/IP 協定族的一種封裝,是應用層與TCP/IP協定族通信的中間軟體抽象層。從設計模式的角度看來,Socket其實就是一個門面模式,它把複雜的TCP/IP協定族隐藏在Socket接口後面,對使用者來說,一組簡單的接口就是全部,讓Socket去組織資料,以符合指定的協定;Socket 還可以認為是一種網絡間不同計算機上的程序通信的一種方法,利用三元組(ip位址,協定,端口)就可以唯一辨別網絡中的程序,網絡中的程序通信可以利用這個标志與其它程序進行互動;Socket 起源于 Unix ,Unix/Linux 基本哲學之一就是“一切皆檔案”,都可以用“打開(open) –> 讀寫(write/read) –> 關閉(close)”模式來進行操作。是以 Socket 也被處理為一種特殊的檔案。

TCP程式設計

Socket表示“打開了一個網絡連結”,而打開一個Socket需要知道目标計算機的IP位址和端口号,再指定協定類型即可。建立TCP連接配接時,主動發起連接配接的叫用戶端,被動響應連接配接的叫伺服器。
  • 用戶端:

輸出結果:

在目錄下生成 sina.html檔案,打開就是新浪首頁。每一步操作都備注了,可以看出用戶端要發起一個網絡請求需要 5 步,建立 socket 時需要指定是那種協定,SOCK_STREAM指定使用面向流的TCP協定。接受完資料後要記得關閉 socket。

  • 服務端:

輸出結果:

以上完成了一個用戶端使用TCP協定送出請求,伺服器接收處理,傳回用戶端資訊的完整過程。以下是TCP程式設計的特點:

  • TCP 提供一種面向連接配接的、可靠的位元組流服務
  • 在一個 TCP 連接配接中,僅有兩方進行彼此通信。廣播和多點傳播不能用于 TCP
  • TCP 使用校驗和,确認和重傳機制來保證可靠傳輸
  • TCP 給資料分節進行排序,并使用累積确認保證資料的順序不變和非重複
  • TCP 使用滑動視窗機制來實作流量控制,通過動态改變視窗的大小進行擁塞控制

    注意:TCP 并不能保證資料一定會被對方接收到,因為這是不可能的。TCP 能夠做到的是,如果有可能,就把資料遞送到接收方,否則就(通過放棄重傳并且中斷連接配接這一手段)通知使用者。是以準确說 TCP 也不是 100% 可靠的協定,它所能提供的是資料的可靠遞送或故障的可靠通知。

UDP程式設計

TCP是建立可靠連接配接,并且通信雙方都可以以流的形式發送資料。相對TCP,UDP則是面向無連接配接的協定。使用UDP協定時,不需要建立連接配接,隻需要知道對方的IP位址和端口号,就可以直接發資料包。但是,能不能到達就不知道了。
  • 缺點:UDP傳輸資料不可靠
  • 優點:和TCP比,速度快,對于不要求可靠到達的資料,就可以使用UDP協定

直接上代碼:

輸出結果:

以上就是UDP協定的使用,UDP的使用與TCP類似,但是不需要建立連接配接。此外,伺服器綁定UDP端口和TCP端口互不沖突,也就是說,UDP的9999端口與TCP的9999端口可以各自綁定。以下是幾個UDP程式設計的特點:

  • UDP 缺乏可靠性。UDP 本身不提供确認,序列号,逾時重傳等機制。UDP 資料報可能在網絡中被複制,被重新排序。即 UDP 不保證資料報會到達其最終目的地,也不保證各個資料報的先後順序,也不保證每個資料報隻到達一次
  • UDP 資料報是有長度的。每個 UDP 資料報都有長度,如果一個資料報正确地到達目的地,那麼該資料報的長度将随資料一起傳遞給接收方。而 TCP 是一個位元組流協定,沒有任何(協定上的)記錄邊界。
  • UDP 是無連接配接的。UDP 客戶和伺服器之前不必存在長期的關系。UDP 發送資料報之前也不需要經過握手建立連接配接的過程。
  • UDP 支援多點傳播和廣播。

TCP三向交握與四次揮手機制

所謂三次握手(Three-way Handshake),是指建立一個 TCP 連接配接時,需要用戶端和伺服器總共發送3個包。

三次握手的目的是連接配接伺服器指定端口,建立 TCP 連接配接,并同步連接配接雙方的序列号和确認号,交換 TCP 視窗大小資訊。在 socket 程式設計中,用戶端執行 connect() 時。将觸發三次握手。

第一次握手(SYN=1, seq=x):

用戶端發送一個 TCP 的 SYN 标志位置1的包,指明用戶端打算連接配接的伺服器的端口,以及初始序号 X,儲存在標頭的序列号(Sequence Number)字段裡。

發送完畢後,用戶端進入 SYN_SEND 狀态。

第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):

伺服器發回确認包(ACK)應答。即 SYN 标志位和 ACK 标志位均為1。伺服器端選擇自己 ISN 序列号,放到 Seq 域裡,同時将确認序号(Acknowledgement Number)設定為客戶的 ISN 加1,即X+1。發送完畢後,伺服器端進入 SYN_RCVD 狀态。

第三次握手(ACK=1,ACKnum=y+1)

用戶端再次發送确認包(ACK),SYN 标志位為0,ACK 标志位為1,并且把伺服器發來 ACK 的序号字段+1,放在确定字段中發送給對方,并且在資料段放寫ISN的+1

發送完畢後,用戶端進入 ESTABLISHED 狀态,當伺服器端接收到這個包時,也進入 ESTABLISHED 狀态,TCP 握手結束。

三次握手的過程的示意圖如下:

python socket_【技術分享】Python3(14) Python 網絡程式設計

三次握手

TCP 的連接配接的拆除需要發送四個包,是以稱為四次揮手(Four-way handshake),也叫做改進的三次握手。用戶端或伺服器均可主動發起揮手動作,在 socket 程式設計中,任何一方執行 close() 操作即可産生揮手操作。

第一次揮手(FIN=1,seq=x)

假設用戶端想要關閉連接配接,用戶端發送一個 FIN 标志位置為1的包,表示自己已經沒有資料可以發送了,但是仍然可以接受資料。

發送完畢後,用戶端進入 FIN_WAIT_1 狀态。

第二次揮手(ACK=1,ACKnum=x+1)

伺服器端确認用戶端的 FIN 包,發送一個确認包,表明自己接受到了用戶端關閉連接配接的請求,但還沒有準備好關閉連接配接。

發送完畢後,伺服器端進入 CLOSE_WAIT 狀态,用戶端接收到這個确認包之後,進入 FIN_WAIT_2 狀态,等待伺服器端關閉連接配接。

第三次揮手(FIN=1,seq=y)

伺服器端準備好關閉連接配接時,向用戶端發送結束連接配接請求,FIN 置為1。

發送完畢後,伺服器端進入 LAST_ACK 狀态,等待來自用戶端的最後一個ACK。

第四次揮手(ACK=1,ACKnum=y+1)

用戶端接收到來自伺服器端的關閉請求,發送一個确認包,并進入 TIME_WAIT狀态,等待可能出現的要求重傳的 ACK 包。

伺服器端接收到這個确認包之後,關閉連接配接,進入 CLOSED 狀态。

用戶端等待了某個固定時間(兩個最大段生命周期,2MSL,2 Maximum Segment Lifetime)之後,沒有收到伺服器端的 ACK ,認為伺服器端已經正常關閉連接配接,于是自己也關閉連接配接,進入 CLOSED 狀态。

四次揮手的示意圖如下:

python socket_【技術分享】Python3(14) Python 網絡程式設計

四次揮手

搞清楚握手和揮手規則,我們就可以設計如何防止或者說如何減少 SYN 攻擊:

  • 縮短逾時(SYN Timeout)時間(TCP KeepAlive)
  • 增加最大半連接配接數
  • 過濾網關防護
  • SYN cookies技術

三次握手

TCP 的連接配接的拆除需要發送四個包,是以稱為四次揮手(Four-way handshake),也叫做改進的三次握手。用戶端或伺服器均可主動發起揮手動作,在 socket 程式設計中,任何一方執行 close() 操作即可産生揮手操作。

第一次揮手(FIN=1,seq=x)

假設用戶端想要關閉連接配接,用戶端發送一個 FIN 标志位置為1的包,表示自己已經沒有資料可以發送了,但是仍然可以接受資料。

發送完畢後,用戶端進入 FIN_WAIT_1 狀态。

第二次揮手(ACK=1,ACKnum=x+1)

伺服器端确認用戶端的 FIN 包,發送一個确認包,表明自己接受到了用戶端關閉連接配接的請求,但還沒有準備好關閉連接配接。

發送完畢後,伺服器端進入 CLOSE_WAIT 狀态,用戶端接收到這個确認包之後,進入 FIN_WAIT_2 狀态,等待伺服器端關閉連接配接。

第三次揮手(FIN=1,seq=y)

伺服器端準備好關閉連接配接時,向用戶端發送結束連接配接請求,FIN 置為1。

發送完畢後,伺服器端進入 LAST_ACK 狀态,等待來自用戶端的最後一個ACK。

第四次揮手(ACK=1,ACKnum=y+1)

用戶端接收到來自伺服器端的關閉請求,發送一個确認包,并進入 TIME_WAIT狀态,等待可能出現的要求重傳的 ACK 包。

伺服器端接收到這個确認包之後,關閉連接配接,進入 CLOSED 狀态。

用戶端等待了某個固定時間(兩個最大段生命周期,2MSL,2 Maximum Segment Lifetime)之後,沒有收到伺服器端的 ACK ,認為伺服器端已經正常關閉連接配接,于是自己也關閉連接配接,進入 CLOSED 狀态。

四次揮手的示意圖如下:

python socket_【技術分享】Python3(14) Python 網絡程式設計

四次揮手

搞清楚握手和揮手規則,我們就可以設計如何防止或者說如何減少 SYN 攻擊:

  • 縮短逾時(SYN Timeout)時間(TCP KeepAlive)
  • 增加最大半連接配接數
  • 過濾網關防護
  • SYN cookies技術

作者:猿來如癡連結:https://www.jianshu.com/p/b0fd63e9fca2來源:簡書簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。

python socket_【技術分享】Python3(14) Python 網絡程式設計