python 網路篇(各地快三幸運彩php原始碼 使用thinkphp框架開發網路程式設計)
一.楔子
你現在已經學會了寫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地址
什麼是埠
因此ip地址精確到具體的一臺電腦,而埠精確到具體的程式。
2.osi七層模型
引子
須知一個完整的計算機系統是由硬體、作業系統、應用軟體三者組成,具備了這三個條件,一臺計算機系統就可以自己跟自己玩了(打個單機遊戲,玩個掃雷啥的)
如果你要跟別人一起玩,那你就需要上網了,什麼是網際網路?
網際網路的核心就是由一堆協議組成,協議就是標準,比如全世界人通訊的標準是英語,如果把計算機比作人,網際網路協議就是計算機界的英語。所有的計算機都學會了網際網路協議,那所有的計算機都就可以按照統一的標準去收發資訊從而完成通訊了。
osi七層模型
人們按照分工不同把網際網路協議從邏輯上劃分了層級:
3.socket概念
socket層
理解socket
Socket是應用層與TCP/IP協議族通訊的中間軟體抽象層,它是一組介面。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket介面後面,對使用者來說,一組簡單的介面就是全部,讓Socket去組織資料,以符合指定的協議。
3.套接字(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 socket sk = 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 socket sk = socket.socket() # 建立客戶套接字 sk.connect(('127.0.0.1',8898)) # 嘗試連線伺服器 sk.send(b'hello!') ret = sk.recv(1024) # 對話(傳送/接收) print(ret) sk.close() # 關閉客戶套接字
話不多說,知己上程式碼吧
tcp程式碼
from socket import socket sk = socket(type=socket.SOCK_STREAM) sk.bind(('127.0.0.1',9090)) sk.listen() while 1: # print(123) conn,addr = sk.accept() # 等待連線 -- 阻塞 # print(456) while 1: # print(789) msg_r = conn.recv(1024).decode('utf-8') # 阻塞等待接收客戶端發來的訊息 # print('jqk') print('接收到來自%s的一個訊息:%s' % (addr, msg_r)) if msg_r == 'q': break msg_s = input('>>>') conn.send(msg_s.encode('utf-8'))# 傳送給客戶端訊息 if msg_s == 'q': break conn.close()# 伺服器和當前客戶端斷開連線,程式回到上一層死迴圈,重新等待客戶端的連線 sk.close() from socket import socket sk = socket() sk.connect(('127.0.0.1',9090)) while 1: msg_s = input('>>>') sk.send(msg_s.encode('utf-8')) if msg_s == 'q': break msg_r = sk.recv(1024).decode('utf-8') print(msg_r) if msg_r == 'q': break sk.close()
udp顏色程式碼
import socket sk = socket.socket(type=socket.SOCK_DGRAM)# udp協議 sk.bind(('127.0.0.1',9090)) dic = {'alex':'\033[0;33;42m','太白':'\033[0;35;40m'} while 1: msg_r,addr = sk.recvfrom(1024)# 接收來自哪裡的訊息 msg_r = msg_r.decode('utf-8')# alex : 我要退學 # 對於msg_r,通過':'分割,獲取下標為0的,也就是name,再去掉name的左右兩邊的空格 name = msg_r.split(':')[0].strip() color = dic.get(name,'')# 獲取字典中 name所對應的 顏色值 print('%s%s \033[0m'%(color,msg_r)) if msg_r == 'q':# 如果當前客戶端想要斷開連線 continue # 伺服器端不應該繼續通話了,應該等待接收另一個客戶端的連線,返回到recvfrom msg_s = input('>>>') sk.sendto(msg_s.encode('utf-8'), addr) if msg_s == 'q': break sk.close() import socket sk = socket.socket(type=socket.SOCK_DGRAM) name = input('請輸入您的名字:>>>') while 1: msg_s = input('>>>') msg_s = name + " : "+msg_s sk.sendto(msg_s.encode('utf-8'),('127.0.0.1',9090))# 發給誰一條訊息 if msg_s is 'q': break msg_r,addr = sk.recvfrom(1024) msg_r = msg_r.decode('utf-8') print(msg_r) if msg_r == 'q': break sk.close()
udp時間同步
import socket import time sk = socket.socket(type=socket.SOCK_DGRAM) sk.bind(('127.0.0.1',9090)) while 1: tm_format,addr = sk.recvfrom(1024) tm_format = tm_format.decode('utf-8')# %Y-%m\%d %H:%M:%S local_tm = time.strftime(tm_format)# 獲取到了對應格式的當前時間 sk.sendto(local_tm.encode('utf-8'),addr)# 返回給客戶端 sk.close() import socket import time sk = socket.socket(type=socket.SOCK_DGRAM) tm_format = input('>>>') while 1: sk.sendto(tm_format.encode('utf-8'),('127.0.0.1',9090)) local_tm,addr = sk.recvfrom(1024) print(local_tm.decode('utf-8')) time.sleep(2)