假期(网络编程)
"""
一、客戶端/服務端架構:1、硬件C/S架構(打印機)2、軟件C/S架構互聯網中處處都是CS架構,服務端與客戶端CS架構與socket的關系- 我們學習socket就是為了完成C/S架構的開發二、OSI七層模型:一個完整的計算機系統是由硬件、操作系統、應用軟件三者組成,一臺計算機只能自己玩自己,要想跟別人玩就需要上網了互聯網的核心就是由一堆協議組成,協議就是標準,比如全世界人通信的標準是英語;如果把計算機比做人,那么互聯網協議就是計算機界的英語了,如果所有的計算機都學會了這門英語,那么就可以互相通信了為何學習socket一定要先學習互聯網協議:- 1、首先我們的目標是基于socket編程,來開發一款自己的cs架構軟件- 2、其次cs架構軟件(軟件屬于應用層)是基于網絡進行通信的- 3、網絡的核心即一堆協議,協議即標準,你想開發一款基于網絡通信的軟件,就必須遵循這些標準三、socket層socket層位于運輸層和應用層之間,即socket抽象層四、socket是什么?socket是應用層與TCP/IP協議族通信的中間軟件抽象層,它是一組接口。在設計模式中,socket其實就是一個門面模式,它吧復雜的TCP/IP協議族隱藏在了socket接口的后面,對用戶來說,一組簡單的接口就是全部,讓socket去組織數據,以符合指定的協議所以我們無需深入理解tcp/udp協議,socket已經幫我們封裝好了,我們只需要遵循socket的規定去編程,寫出的程序自然符合標準- 也有人將socket說成是IP+port,IP是用來標識互聯網中的一臺主機的位置,而port是用來標識這臺主機上的一個應用程序,IP地址配置到網卡上的,而port是應用程序開啟的,IP與port的綁定就標識了互聯網中獨一無二的應用程序程序的pid是同一臺機器上不同進程或者線程的標識五、套接字的分類:- 基于文件類型的套接字家族套接字家族的名字:AF_UNIXunix一切皆文件,基于文件的套接字調用的就是底層文件系統來取數據,兩個套接字進程運行在同一機器,可以通過訪問同一個間接完成通信。- 基于網絡類型的套接字家族套接字家族的名字:AF_INET···所有的地址家族中,AF_INET是使用最廣泛的一個,python支持很多種地址家族,但是由于我們只關心網絡編程,所以我們大部分時間都只是使用AF_INET六、套接字的工作流程:一個生活中的場景:你要給你前對象打電話,先撥號,前對象聽到電話鈴聲后拿起電話,這時候你倆就建立起來了不正當的鏈接,然后就可以進行不正當的交易了。交易完成后,掛斷電話結束此次交談;先從服務端說起,服務端先初始化socket,然后與端口綁定(bind),對端口進行監聽(listen),調用accept阻塞,等待客戶端鏈接在這個時候如果有客戶端初始化一個socket,然后鏈接服務器(connect),如果鏈接成功,這時客戶端與服務端的鏈接就建立了。客戶端發送數據請求,服務端接收請求并處理,然后把回應數據發送給客戶端,客戶端讀取數據,關閉鏈接,交互結束- socket函數的用法import socketsocket.socket(socket_family,socket_type,protocal=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)由于socket模塊中有太多的屬性,我們直接在這里使用 from xxx import * 的語句導入,這樣就可以減少代碼量eg:tcpsock = socket(AF_INET,SOCK_STREAM)- 服務端套接字函數s.bind()綁定(主機,端口號)到套接字s.listen()開始tcp監聽s.accept()被動接受tcp客戶的連接,(阻塞式)等待連接的到來- 客戶端套接字函數c.connect()被動初始化tcp服務器連接c.connect_ex() connect()函數的擴展版本,出錯時返回錯誤碼,而不是拋出異常- 公共用途的套接字函數s.recv()接受tcp數據s.send()發送tcp數據(send在待發送數據量大于已緩存區剩余的空間時,數據丟失,不會發完)s.sendall()發送完整的tcp數據(本質就是循環send,···數據不會丟失)s.recvfrom()接受udp數據s.sendto()發送udp數據s.getpeername()鏈接到當前套接字的遠程地址s.getsockname()當前套接字的地址s.getsockopt()返回指定套接字的參數s.setsockopt()設置指定套接字的參數s.close()關閉套接字鏈接- 面向鎖的套接字方法s.setblocking()設置套接字的阻塞與非阻塞模式s.settimeout()設置阻塞套接字操作的超時時間s.gettimeout()得到阻塞套接字操作的超時時間- 面向文件的套接字函數s.fileno()套接字的文件描述符s.makefile()創建一個與該套接字相關的文件
七、基于tcp的套接字tcp是基于鏈接的,必須先啟動服務端,然后再啟動客戶端去鏈接服務端- tcp服務端:server = socket() #創建服務器套接字server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)server.bind() #把地址綁定到套接字server.listen() #監聽鏈接while true: #服務器無限循環client,addr = server.accept() #接受客戶端鏈接while True: #通信循環client.recv()/client.send() #接收與發送數據client.close() #關閉客戶端套接字server.close() #關閉服務器套接字- tcp客戶端:client = socket() #創建客戶端套接字client.connect() #嘗試鏈接服務器while True:client.send()/client.recv() #發送/接收數據client.close() #關閉客戶端套接字八、基于udp的套接字- udp服務端server = socket() #創建服務器套接字server.bind() #綁定套接字地址while True: #服務器無線循環client,addr = server.recvfrom()/server.sendto() #接收與發送數據server.close() #關閉服務器套接字- udp客戶端client = socket() #創建客戶端套接字while True: #通信循環client.sendto()/client.recvfrom() #發送與接收數據client.close() #關閉客戶端套接字九、粘包現象(了解)如果當我們用socket模擬cmd執行遠程命令時,有些數據太長,超過了1024個字節,一次接受不完,就會造成粘包- 什么是粘包?只有tcp才有粘包現象,udp永遠不會粘包,因為udp是基于流收發數據的所謂粘包的問題主要還是因為接收方不知道消息之間的界限,不知道一次性提取多少數據造成的- 粘包的解決- struct模塊- 自定義報頭- ···- 什么時候才會發生粘包?發送端需要等緩沖區滿才發送出去,造成粘包(發送數據時間間隔很短,數據很小會喝到一起,產生粘包)接收方不及時接收緩沖區的包,造成多個包接收產生粘包- 了解tcp是可靠傳輸,udp是不可靠傳輸十、socketserver模塊- 終極必殺技"""
?
轉載于:https://www.cnblogs.com/52-qq/p/8449470.html
總結
- 上一篇: Kafka学习之(五)搭建kafka集群
- 下一篇: wannalfy 挑战赛8 F 白云的