1.硬件C/S架構(打印機)python
打印機做爲一個服務端,電腦鏈接打印機進行打印編程
2.軟件C/S架構設計模式
互聯網中到處是C/S架構瀏覽器
如谷歌網站是服務端,你的瀏覽器是客戶端(B/S架構也是C/S架構的一種)緩存
騰訊做爲服務端爲你提供視頻,你得下個騰訊視頻客戶端才能看它的視頻)安全
C/S架構與socket的關係:服務器
咱們學習socket就是爲了完成C/S架構的開發markdown
計算機之間通信須要遵循必定的互聯網協議,好比tcp/ip協議,大量的計算機之間進行通信組成了計算機網絡,網絡的核心即一堆協議,協議即標準,因爲tcp/ip協議太過於複雜,這時須要用socket層對tcp/ip協議進行精簡,提供相應的接口以便更加方便的調用。因此學習socket必定要先學習互聯網協議。網絡
互聯網協議按照功能不一樣分爲osi七層或tcp/ip五層或tcp/ip四層架構
每層運行常見物理設備
TCP/IP 是一類協議系統,它是用於網絡通訊的一套協議集合,傳統上來講 TCP/IP 被認爲是一個四層協議。
物理層:主要是指物理層次的一些接口,好比電纜等.
提供計算機互通的物理介質, 基於電器特性發送高低電壓(電信號),高電壓對應數字1,低電壓對應數字0
數據鏈路層:
定義電信號的分組方式,使用以太網協議封裝數據格式(數據報頭(18個字節雙方地址+數據類型)+數據)
提供獨立於硬件的邏輯尋址,實現物理地址與邏輯地址的轉換.
在 TCP / IP 協議族中,網絡層協議包括 IP 協議(網際協議),ICMP 協議( Internet 互聯網控制報文協議),以及 IGMP 協議( Internet 組管理協議).
網絡層引入一套新的地址用來區分不一樣的廣播域/子網,這套地址即網絡地址(IPV4/IPV6)
爲網絡提供了流量控制,錯誤控制和確認服務.
在 TCP / IP 協議族中有兩個互不相同的傳輸協議: TCP(傳輸控制協議)和 UDP(用戶數據報協議).
創建端口到端口的通訊(應用軟件使用的端口號)。
爲網絡排錯,文件傳輸,遠程控制和 Internet 操做提供具體的應用程序
數據包在 TCP / IP 協議中數據先由上往下將數據裝包,而後由下往上拆包
在裝包的時候,每一層都會增長一些信息用於傳輸,這部分信息就叫報頭,當上層的數據到達本層的時候,會將數據加上本層的報頭打包在一塊兒,繼續往下傳遞.
在拆包的時候,每一層將本層須要的報頭讀取後,就將剩下的數據往上傳.
這個過程有點像俄羅斯套娃,因此有時候人們也會用俄羅斯套娃來形容這個過程.
三次握手:1.客戶端對服務端發送同步請求(創建鏈接通道);2.服務端響應後,發送同步請求(創建鏈接通道)和發送確認數據(這裏的兩個請求被合併成一個了);3.客戶端向服務端發送確認數據。
四次揮手:1.客戶端發送端口結束包給服務端,2.服務端收到之後返回確認信息給客戶端;3.服務端發送端口結束包給客戶端;4.客戶端確認信息返回給服務端。
區別:四次揮手的過程當中,服務端返回給客戶端的確認信息以後不會馬上關閉,有可能會繼續給客戶端發送數據,因此必須得有四次揮手
Socket是應用層與TCP/IP協議族通訊的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來講,一組簡單的接口就是所有,讓Socket去組織數據,以符合指定的協議。
因此,咱們無需深刻理解tcp/udp協議,socket已經爲咱們封裝好了,咱們只須要遵循socket的規定去編程,寫出的程序天然就是遵循tcp/udp標準的。
socket中文翻譯爲套接字,socket英文本義爲孔和插座的意思。
套接字起源於 20 世紀 70 年代加利福尼亞大學伯克利分校版本的 Unix,即人們所說的 BSD Unix。 所以,有時人們也把套接字稱爲「伯克利套接字」或「BSD 套接字」。一開始,套接字被設計用在同 一臺主機上多個應用程序之間的通信。這也被稱進程間通信,或 IPC。套接字有兩種(或者稱爲有兩個種族),分別是基於文件型的和基於網絡型的。
*基於文件類型的套接字家族*
套接字家族的名字:AF_UNIX
unix一切皆文件,基於文件的套接字調用的就是底層的文件系統來取數據,兩個套接字進程運行在同一機器,能夠經過訪問同一個文件系統間接完成通訊
*基於網絡類型的套接字家族*
套接字家族的名字:AF_INET
還有AF_INET6被用於ipv6,還有一些其餘的地址家族,全部地址家族中,AF_INET是使用最普遍的一個,python支持不少種地址家族.
*family(socket家族)*
socket.AF_UNIX:用於本機進程間通信,爲了保證程序安全,兩個獨立的程序(進程)間是不能互相訪問彼此的內存的,但爲了實現進程間的通信,能夠經過建立一個本地的socket來完成
socket.AF_INET:(還有AF_INET6被用於ipv6,還有一些其餘的地址家族,不過,他們要麼是隻用於某個平臺,要麼就是已經被廢棄,或者是不多被使用,或者是根本沒有實現,全部地址家族中,AF_INET是使用最普遍的一個,python支持不少種地址家族,可是因爲咱們只關心網絡編程,因此大部分時候我麼只使用AF_INET)
*socket type類型*
socket.SOCK_STREAM #for tcp
socket.SOCK_DGRAM #for udp
socket.SOCK_RAW #原始套接字,普通的套接字沒法處理ICMP、IGMP等網絡報文,而SOCK_RAW能夠;其次,SOCK_RAW也能夠處理特殊的IPv4報文;此外,利用原始套接字,能夠經過IP_HDRINCL套接字選項由用戶構造IP頭。
socket.SOCK_RDM #是一種可靠的UDP形式,即保證交付數據報但不保證順序。SOCK_RAM用來提供對原始協議的低級訪問,在須要執行某些特殊操做時使用,如發送ICMP報文。SOCK_RAM一般僅限於高級用戶或管理員運行的程序使用。
socket.SOCK_SEQPACKET #廢棄了
一個生活中的場景。你要打電話給一個朋友,先撥號,朋友聽到電話鈴聲後提起電話,這時你和你的朋友就創建起了鏈接,就能夠講話了。等交流結束,掛斷電話結束這次交談。 生活中的場景就解釋了這工做原理。
服務器端先初始化Socket,而後與端口綁定(bind),對端口進行監聽(listen),調用accept阻塞,等待客戶端鏈接。在這時若是有個客戶端初始化一個Socket,而後鏈接服務器(connect),若是鏈接成功,這時客戶端與服務器端的鏈接就創建了。客戶端發送數據請求,服務器端接收請求並處理請求,而後把迴應數據發送給客戶端,客戶端讀取數據,最後關閉鏈接,一次交互結束.
s.bind() 綁定(主機,端口號)到套接字
s.listen() 開始TCP監聽
s.accept() 被動接受TCP客戶的鏈接,(阻塞式)等待鏈接的到來
s.connect() 主動初始化TCP服務器鏈接
s.connect_ex() connect()函數的擴展版本,出錯時返回出錯碼,而不是拋出異常
s.recv() 接收數據
s.send() 發送數據(send在待發送數據量大於己端緩存區剩餘空間時,數據丟失,不會發完,可後面經過實例解釋)
s.sendall() 發送完整的TCP數據(本質就是循環調用send,sendall在待發送數據量大於己端緩存區剩餘空間時,數據不丟失,循環調用send直到發完)
s.sendto() 發送UDP數據
s.recvfrom()接收UDP數據 Receive data from the socket. The return value is a pair (bytes, address)
s.getpeername() 鏈接到當前套接字的遠端的地址
s.close() 關閉套接字
socket.setblocking(flag) #True or False,設置socket爲非阻塞模式,之後講io異步時會用
socket.getaddrinfo(host, port, family=0, type=0, proto=0, flags=0) 返回遠程主機的地址信息,例子 socket.getaddrinfo('google.com',80)
socket.getfqdn() 拿到本機的主機名
socket.gethostbyname() 經過域名解析ip地址
s.getsockopt() 返回指定套接字的參數
s.setsockopt() 設置指定套接字的參數
s.setblocking() 設置套接字的阻塞與非阻塞模式
s.settimeout() 設置阻塞套接字操做的超時時間
s.gettimeout() 獲得阻塞套接字操做的超時時間
s.fileno() 套接字的文件描述符
s.makefile() 建立一個與該套接字相關的文件
參考連接