PYTHON核心編程(第三版)——第1部分第二章_網絡編程

在網易工作這半年來說,單純的寫了很多奇奇怪怪的腳本,比如說在沒有代碼權限的情況下如何得到QA測試的代碼覆蓋率?到頭來還是通過這個網絡編程來解決,之前沒有接觸過網絡編程,直接現學現賣完成任務。

網易有好處在吧,自己設計規劃一個系統,客戶端實現的功能,服務端實現的功能,還需要規劃每個功能點,畫時序圖,說實話這是原來在華爲根本接觸不到的,以前在華爲自己只是負責一個小功能的實現,基本上pm給出開發文檔,按部就班實現就好了,吃麪條,PM說你負責擀麪,就把面擀好了就行了,唯一的難度在於讀懂原來的代碼;在網易,一切從零開始,說白了就是要吃麪條,沒有面粉,也沒有小麥,只有一塊地和一把種子。

以上就是發牢騷,沒有貶低沒有褒獎。

------------------------------------------------------------------------------------------------------------------------------

作者首先就是引用下大佬的話,IPV4用完了,IPV6是出路。

本章內容:簡介;客戶端/服務器架構;套接字:通信端點; Python 中的網絡編程; *SocketServer 模塊; *Twisted 框架介紹;相關模塊。

2.1簡介

簡介。

2.2客戶端/服務端架構

簡要描述下CS架構,用戶作爲客戶端一次性請求永久運行的服務端。軟硬件都可以用。

2.2.1硬件客戶端/服務器架構

舉例子:打印機,文件服務器

2.2.2軟件客戶端/服務器架構

舉例子:web服務器,數據庫服務器,窗體服務器(這個有點抽象的)

2.2.3銀行出納員作爲服務器嗎

舉例說明cs架構:出納員作爲服務器“永久”在線服務隨時要來的客戶。

2.2.4客戶端/服務器網絡編程

服務器創建通信端點,等待客戶端連接並相應他們的請求,結束後通信終止。

2.3套接字:通信端點

套接字就是上面提到的通信端點。

2.3.1套接字

套接字可以比作電話線那個插孔;

AF:address family

現在用於進程間通訊(同一個計算機上),python用的AF_UNIX。

基於網絡的,現在用的AF_INET比較廣泛

總的來說,Python 只支持 AF_UNIX、 AF_NETLINK、 AF_TIPC 和AF_INET家族。

這章講的是網絡編程,所以使用AF_INET

2.3.3套接字地址:主機-端口對   重點

1.面向連接的套接字(TCP)

第一種TCP:是面向連接的,通訊之前必須建立一個連接。提供序列化的、可靠的和不重複的數據交付,沒有記錄邊界。每條信息都可以拆分成多個片段,並且每一條消息片段都確保能夠到達目的地,然後順序的拼接起來,最後將信息完整的傳遞給程序。

爲了創建TCP套接字,必須使用 SOCK_STREAM 作爲套接字類型。

因爲這些套接字(AF_INET)的網絡版本使用因特網協議( IP) 來搜尋網絡中的主機,所以整個系統通常結合這兩種協議( TCP 和 IP) 來進行。

TCP也可以用本地的套接字(非網絡,比如AF_LOCAL/ AF_UNIX),本地的就沒有使用IP地址。

2.無連接的套接字(UDP)

在通訊開始不需要建立連接,傳輸過程中無法確保它的順序性、可靠性和重複性,但是卻記錄了數據邊界,也就是說數據是整體發送的,並不是切分片段發送。

這玩意紙面數據這麼差誰用?但是它維護成本低,根本不用管,所以性能更好。

使用 SOCK_DGRAM 作爲套接字類型。

因爲這些套接字也使用因特網協議來尋找網絡中的主機,所以這個系統也有一個更加普通的名字,即這兩種協議( UDP 和IP)的組合名字,或 UDP/ IP。

2.4Python中的網絡編程

2.4.1socket() 模塊函數

創建套接字的一般語法是:socket( socket_family, socket_type, protocol = 0)

socket_family 是 AF_UNIX 或 AF_INET

socket_type是 SOCK_STREAM 或 SOCK_DGRAM

protocol通常省略,默認爲 0。

創建TCP/IP套接字:tcpSock = socket.socket( socket.AF_INET, socket.SOCK_STREAM)

創建UDP/IP套接字:udpSock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM)

2.4.2套接字對象(內置)方法

2.4.3 創建 TCP 服務器

創建 TCP 服務器僞代碼,目的是理解創建過程。

ss = socket() # 創建服務器套接字 
ss.bind() # 套接字與地址綁定 
ss.listen() # 監聽連接 
inf_loop: # 服務器無限循環 
    cs = ss.accept() # 接受客戶端連接 
    comm_loop: # 通信循環 
        cs.recv()/ cs.send() # 對話(接收/發送) 
    cs.close() # 關閉客戶端套接字 
ss.close() # 關閉服務器套接字#(可選)

socket.socket () 所有套接字都是通過使用 socket ()函數來創建的。

ss.listen()監聽開始之後,服務器開始無線循環中。

cs = ss.accept(),這個就是接受客戶端的函數,沒有連接的情況下,這個一般是阻塞的,就是說這個過程運行到這就卡住,指導有人連接後開始下一步。

cs.recv()/ cs.send()這個就是相互發送信息的函數

cs.close()關閉了連接

ss.close()服務端也關閉了。

上面這個是單服務端的例子,也就是服務端一次只能連接一個客戶端。

核心提示:多線程處理客戶端請求

書裏沒有寫,可以參考下我寫的這個例程:https://blog.csdn.net/marwenx/article/details/104760791

接下來是兩個例子,一個python2一個python3,直接將上面這些僞代碼實例化了,不在贅述。

2.4.4 創建 TCP 客戶端

僞代碼

cs = socket() # 創建客戶端套接字 
cs.connect() # 嘗試連接服務器 
comm_loop: # 通信循環 
    cs.send()/ cs.recv() # 對話(發送/接收) 
cs.close() # 關閉客戶端套接字

所有套接字都是利用 socket.socket() 創建的。

利用套接字的 connect() 方法直接創建一個到服務器的連接。

cs.close() 關閉套接字,終止此次連接。

例子不在贅述。

2.4.5 執行 TCP 服務器和客戶端

這個就是動手實踐下就好,先運行服務端,再運行客戶端,第一次就很好玩。

核心提示:優雅地退出和調用服務器 close() 方法

這個書裏建議是用一個 try-except 語句中的 except 子句中,監控 EOFError 或KeyboardInterrupt異常,這樣你就可以在 except 或 finally 字句中關閉服務器的套接字。

我一般是發送一個特殊的字符串過去,比如說“exit”

2.4.6 創建 UDP 服務器

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章