標籤:努力 cep import smis sock 大致 加利福尼亞 版本 recv
一.楔子
你現在已經學會了寫python代碼,假如你寫了兩個python檔案a.py和b.py,分別去運行,你就會發現,這兩個python的檔案分別啟動並執行很好。但是如果這兩個程式之間想要傳遞一個資料,你要怎麼做呢?
這個問題以你現在的知識就可以解決了,我們可以建立一個檔案,把a.py想要傳遞的內容寫到檔案中,然後b.py從這個檔案中讀取內容就可以了。
但是當你的a.py和b.py分別在不同電腦上的時候,你要怎麼辦呢?
類似的機制有電腦網盤,qq等等。我們可以在我們的電腦上和別人聊天,可以在自己的電腦上向網盤中上傳、下載內容。這些都是兩個程式在通訊。
二.軟體開發的架構
我們瞭解的涉及到兩個程式之間通訊的應用大致可以分為兩種:
第一種是應用類:qq、、網盤、優酷這一類是屬於需要安裝的案頭應用
第二種是web類:比如百度、知乎、部落格園等使用瀏覽器訪問就可以直接使用的應用
這些應用的本質其實都是兩個程式之間的通訊。而這兩個分類又對應了兩個軟體開發的架構~
1.C/S架構
C/S即:Client與Server ,中文意思:用戶端與伺服器端架構,這種架構也是從使用者層面(也可以是物理層面)來劃分的。
這裡的用戶端一般泛指用戶端應用程式EXE,程式需要先安裝後,才能運行在使用者的電腦上,對使用者的電腦作業系統環境依賴較大。
2.B/S架構
B/S即:Browser與Server,中文意思:瀏覽器端與伺服器端架構,這種架構是從使用者層面來劃分的。
Browser瀏覽器,其實也是一種Client用戶端,只是這個用戶端不需要大家去安裝什麼應用程式,只需在瀏覽器上通過HTTP請求伺服器端相關的資源(網頁資源),用戶端Browser瀏覽器就能進行增刪改查。
回到頂部三.網路基礎
網路基礎
1.一個程式如何在網路上找到另一個程式?
首先,程式必須要啟動,其次,必須有這台機器的地址,我們都知道我們人的地址大概就是國家\省\市\區\街道\樓\門牌號這樣字。那麼每一台連網的機器在網路上也有自己的地址,它的地址是怎麼表示的呢?
就是使用一串數字來表示的,例如:100.4.5.6
IP地址是指互連網協議地址(英語:Internet Protocol Address,又譯為網際協議地址),是IP Address的縮寫。IP地址是IP協議提供的一種統一的地址格式,它為互連網上的每一個網路和每一台主機分配一個邏輯地址,以此來屏蔽物理地址的差異。IP地址是一個32位的位元,通常被分割為4個“8位位元”(也就是4個位元組)。IP地址通常用“點分十進位”表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之間的十進位整數。例:點分十進IP地址(100.4.5.6),實際上是32位位元(01100100.00000100.00000101.00000110)。
什麼是ip地址?
"連接埠"是英文port的意譯,可以認為是裝置與外界通訊交流的出口。
什麼是連接埠?
因此ip地址精確到具體的一台電腦,而連接埠精確到具體的程式。
2.osi七層模型
引子
須知一個完整的電腦系統是由硬體、作業系統、應用軟體三者組成,具備了這三個條件,一台電腦系統就可以自己跟自己玩了(打個單機遊戲,玩個掃雷啥的)
如果你要跟別人一起玩,那你就需要上網了,什麼是互連網?
互連網的核心就是由一堆協議組成,協議就是標準,比如全世界人通訊的標準是英語,如果把電腦比作人,互連網協議就是電腦界的英語。所有的電腦都學會了互連網協議,那所有的電腦都就可以按照統一的標準去收發資訊從而完成通訊了。
osi七層模型
人們按照分工不同把互連網協議從邏輯上劃分了層級:
3.socket概念socket層
理解socket
Socket是應用程式層與TCP/IP協議族通訊的中間軟體抽象層,它是一組介面。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket介面後面,對使用者來說,一組簡單的介面就是全部,讓Socket去組織資料,以符合指定的協議。
其實站在你的角度上看,socket就是一個模組。我們通過調用模組中已經實現的方法建立兩個進程之間的串連和通訊。也有人將socket說成ip+port,因為ip是用來標識互連網中的一台主機的位置,而port是用來標識這台機器上的一個應用程式。所以我們只要確立了ip和port就能找到一個應用程式,並且使用socket模組來與之通訊。
站在我的角度看socket3.通訊端(socket)的發展史
通訊端起源於 20 世紀 70 年代加利福尼亞大學伯克利分校版本的 Unix,即人們所說的 BSD Unix。 因此,有時人們也把通訊端稱為“伯克利通訊端”或“BSD 通訊端”。一開始,通訊端被設計用在同 一台主機上多個應用程式之間的通訊。這也被稱進程間通訊,或 IPC。通訊端有兩種(或者稱為有兩個種族),分別是基於檔案型的和基於網路型的。
基於檔案類型的通訊端家族
通訊端家族的名字:AF_UNIX
unix一切皆檔案,基於檔案的通訊端調用的就是底層的檔案系統來取資料,兩個通訊端進程運行在同一機器,可以通過訪問同一個檔案系統間接完成通訊
基於網路類型的通訊端家族
通訊端家族的名字:AF_INET
(還有AF_INET6被用於ipv6,還有一些其他的地址家族,不過,他們要麼是只用於某個平台,要麼就是已經被廢棄,或者是很少被使用,或者是根本沒有實現,所有地址家族中,AF_INET是使用最廣泛的一個,python支援很多種地址家族,但是由於我們只關心網路編程,所以大部分時候我麼只使用AF_INET)
4.tcp協議和udp協議
TCP(Transmission Control Protocol)可靠的、連線導向的協議(eg:打電話)、傳輸效率低全雙工系統通訊(發送緩衝&接收緩衝)、面向位元組流。使用TCP的應用:Web瀏覽器;電子郵件、檔案傳輸程式。
UDP(User Datagram Protocol)不可靠的、不需連線的服務,傳輸效率高(發送前時延小),一對一、一對多、多對一、多對多、面向報文,盡最大努力服務,無擁塞控制。使用UDP的應用:網域名稱系統 (DNS);視頻流;IP語音(VoIP)。
我知道說這些你們也不懂,直接。
回到頂部
四.通訊端(socket)初使用基於TCP協議的socket
tcp是基於連結的,必須先啟動服務端,然後再啟動用戶端去連結服務端
server端
import socketsk = socket.socket()sk.bind((‘127.0.0.1‘,8898)) #把地址綁定到通訊端sk.listen() #監聽連結conn,addr = sk.accept() #接受用戶端連結ret = conn.recv(1024) #接收用戶端資訊print(ret) #列印用戶端資訊conn.send(b‘hi‘) #向用戶端發送資訊conn.close() #關閉用戶端通訊端sk.close() #關閉伺服器通訊端(可選)
client端
import socketsk = socket.socket() # 建立客戶通訊端sk.connect((‘127.0.0.1‘,8898)) # 嘗試串連伺服器sk.send(b‘hello!‘)ret = sk.recv(1024) # 對話(發送/接收)print(ret)sk.close() # 關閉客戶通訊端
問題:有的同學在重啟服務端時可能會遇到
解決方案:
#加入一條socket配置,重用ip和連接埠import socketfrom socket import SOL_SOCKET,SO_REUSEADDRsk = socket.socket()sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加sk.bind((‘127.0.0.1‘,8898)) #把地址綁定到通訊端sk.listen() #監聽連結conn,addr = sk.accept() #接受用戶端連結ret = conn.recv(1024) #接收用戶端資訊print(ret) #列印用戶端資訊conn.send(b‘hi‘) #向用戶端發送資訊conn.close() #關閉用戶端通訊端sk.close() #關閉伺服器通訊端(可選)
基於UDP協議的socket
udp是無連結的,啟動服務之後可以直接接受訊息,不需要提前建立連結
簡單使用 server端
import socketudp_sk = socket.socket(type=socket.SOCK_DGRAM) #建立一個伺服器的通訊端udp_sk.bind((‘127.0.0.1‘,9000)) #綁定伺服器通訊端msg,addr = udp_sk.recvfrom(1024)print(msg)udp_sk.sendto(b‘hi‘,addr) # 對話(接收與發送)udp_sk.close() # 關閉伺服器通訊端
client端
import socketip_port=(‘127.0.0.1‘,9000)udp_sk=socket.socket(type=socket.SOCK_DGRAM)udp_sk.sendto(b‘hello‘,ip_port)back_msg,addr=udp_sk.recvfrom(1024)print(back_msg.decode(‘utf-8‘),addr)
python之路——網路編程