Python 爬蟲 (三) - Socket 網路程式設計

發表於2017-08-25

python的網路變成比c語言簡單許多, 封裝許多底層的實現細節, 方便程式設計師使用的同時, 也使程式設計師比較難了解一些底層的東西, 我覺得學網路程式設計還是用c語言更好一點.

寫這篇博文, 也希望回顧並整理一下以前學過的c語言和linux下一些東西, 會將一些Linux網路程式設計的函式和Python網路變成函式做一個簡單的對照, 方便記憶

1. Socket套接字的概念


Socket(翻譯為套接字, 我覺得很挫),是作業系統核心中的一個資料結構,它是網路中的節點進行相互通訊的門戶。它是網路程式的ID。網路通訊,歸根到底還是程式間的通訊(不同計算機上的程式間通訊, 又稱程式間通訊, IP協議進行的主要是端到端通訊)。在網路中,每一個節點(計算機或路由)都有一個網路地址,也就是IP地址。兩個程式通訊時,首先要確定各自所在的網路節點的網路地址。但是,網路地址只能確定程式所在的計算機,而一臺計算機上很可能同時執行著多個程式,所以僅憑網路地址還不能確定到底是和網路中的哪一個程式進行通訊,因此套介面中還需要包括其他的資訊,也就是埠號(PORT)。在一臺計算機中,一個埠號一次只能分配給一個程式,也就是說,在一臺計算機中,埠號和程式之間是一一對應關係。

所以,使用埠號和網路地址的組合可以唯一的確定整個網路中的一個網路程式.

埠號的範圍從0~65535,一類是由網際網路指派名字和號碼公司ICANN負責分配給一些常用的應用程式固定使用的“周知的埠”,其值一般為0~1023, 使用者自定義埠號一般大於等於1024, 我比較喜歡用8888

每一個socket都用一個半相關描述{協議、本地地址、本地埠}來表示;一個完整的套接字則用一個相關描述{協議、本地地址、本地埠、遠端地址、遠端埠}來表示。socket也有一個類似於開啟檔案的函式呼叫,該函式返回一個整型的socket描述符,隨後的連線建立、資料傳輸等操作都是通過socket來實現的

1.1. Socket型別

socket型別在Liunx和Python是一樣的, 只是Python中的型別都定義在socket模組中, 呼叫方式socket.SOCK_XXXX

  • 流式socket(SOCK_STREAM) 用於TCP通訊

流式套接字提供可靠的、面向連線的通訊流;它使用TCP協議,從而保證了資料傳輸的正確性和順序性

  • 資料包socket(SOCK_DGRAM) 用於UDP通訊

資料包套接字定義了一種無連線的服務,資料通過相互獨立的報文進行傳輸,是無序的,並且不保證是可靠、無差錯的。它使用資料包協議UDP

  • 原始socket(SOCK_RAW) 用於新的網路協議實現的測試等

原始套接字,普通的套接字無法處理ICMP、IGMP等網路報文,而SOCK_RAW可以, 其次,SOCK_RAW也可以處理特殊的IPv4報文;此外,利用原始套接字,可以通過IP_HDRINCL套接字選項由使用者構造IP頭。

2. Socket程式設計


2.1. TCP通訊

TCP通訊的基本步驟如下:
服務端:socket—bind—listen—while(True){—accept—recv—send—-}—close
客戶端:socket———————————-connect—send—recv——-close

48

TCP

socket函式
使用給定的地址族、套接字型別、協議編號(預設為0)來建立套接字

2.1.1. 伺服器端函式

bind函式
將套接字繫結到地址, python下,以元組(host,port)的形式表示地址, Linux下使用sockaddr_in結構體指標

listen函式
使伺服器的這個埠和IP處於監聽狀態,等待網路中某一客戶機的連線請求。如果客戶端有連線請求,埠就會接受這個連線

accept函式
接受遠端計算機的連線請求,建立起與客戶機之間的通訊連線。伺服器處於監聽狀態時,如果某時刻獲得客戶機的連線請求,此時並不是立即處理這個請求,而是將這個請求放在等待佇列中,當系統空閒時再處理客戶機的連線請求。

2.1.2. 客戶端函式

connect函式
用來請求連線遠端伺服器

2.1.3. 通用函式

接收遠端主機傳來的資料

recv函式

send函式
傳送資料給指定的遠端主機

close函式
關閉套接字

2.2. 簡單的客戶端伺服器TCP連線

一個簡單的回顯伺服器和客戶端模型, 客戶端發出的資料, 伺服器會回顯到客戶端的終端上(只是一個簡單的模型, 沒考慮錯誤處理等問題)

2.2.1. 帶錯誤處理的客戶端伺服器TCP連線

在進行網路程式設計時, 最好使用大量的錯誤處理, 能夠儘量的發現錯誤, 也能夠使程式碼顯得更加嚴謹

2.3. UDP通訊

UDP通訊流程圖如下:
服務端:socket—bind—recvfrom—sendto—close
客戶端:socket———-sendto—recvfrom—close

48
UDP

sendto()函式
傳送UDP資料, 將資料傳送到套接字

recvfrom()函式
接受UDP套接字的資料, 與recv()類似

2.4. 簡單的客戶端伺服器UDP連線

2.5. 其他

3. 參考連結


python-socket官方文件

相關文章