學習python課程第二十六天

一.    傳輸層算法

  在上述三層協議中咱們,ip協議幫咱們定位到子網絡. mac地址幫咱們定位到一臺計算機,並與其通信,編程

  但本質上,計算機的通信是爲了應用程序可以通信,而一臺計算機上不可能運行一個應用程序設計模式

 

  問題:緩存

    就像咱們同時運行QQ軟件和微信軟件, 當計算機收到一個數據包時, 須要知道這個數據包究竟是給服務器

    哪一個應用程序的.微信

 

  解決方案:網絡

    爲每個應用程序綁定一個端口號,  端口號就是一個數字, 取值範圍爲 0 -- 65536 其中 0 -- 1023是socket

    系統保留的tcp

  再次捋清思路:函數

    端口定位應用程序, ip 定位網絡, mac 定位計算機

    能夠經過這三個地址,找到全世界計算機中惟一的一個應用程序, 使咱們編寫網絡應用程序成爲可能.

 

 

  

  傳輸層協議 :

    爲何要有傳輸層協議 ?

      應用程序可相互傳遞數據了, 還記得在ip協議中有一個路由算法麼? 會自動選擇最佳的傳輸路徑,

      將致使你的數據包可能走了不一樣的路線, 形成接受順序錯亂, 以及發生丟包等, 爲了保證數據傳輸的

      完整性, 誕生了傳輸層協議!

 

 

    TCP :基於連接傳輸數據, 可保證數據傳輸的完整性

      優勢 :經過三次握手來與服務器創建鏈接

          能夠保證數據的完整性.

           a機器給b機器發送數據包, 要求b機器必須當即返回一個確認包,

           a機器會等待一段時間,若是超時尚未收到確認, 則重發數據.       

      缺點:

        傳輸效率低.

      使用場景 :  文字聊天. 支付寶轉帳等,

 

    UDP : 不須要創建鏈接,直接發送

      缺點:

        不能保證數據的完整性

      優勢:

        傳輸效率比TCP高不少

      使用場景 :  視頻通話,語音通話, 遊戲等.

 

 

    socket 是什麼?

    

      Socket是應用層與TCP/IP協議族通訊的中間軟件抽象層,它是一組接口。在設計模式中,

      Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來講,

      一組簡單的接口就是所有,讓Socket去組織數據,以符合指定的協議。

      因此,咱們無需深刻理解tcp/udp協議,socket已經爲咱們封裝好了,咱們只須要遵循socket的

      規定去編程,寫出的程序天然就是遵循tcp/udp標準的。

 

    使用 socket:

      在使用socket的時候用戶須要關心的是, ip地址, port端口. 傳輸協議TCP/UDP,你要發送的數據data

      在寫網絡編程的時候,必然是兩臺代碼, 對應着客戶端和服務器.

 

    socket 的工做流程 :

       一個生活中的場景。你要打電話給一個朋友,先撥號,朋友聽到電話鈴聲後提起電話,

      這時你和你的朋友就創建起了鏈接,就能夠講話了。等交流結束,掛斷電話結束這次交談。

      生活中的場景就解釋了這工做原理。

 

    

      先從服務器端提及。服務器端先初始化Socket,而後與端口綁定(bind),對端口進行監聽(listen),

      調用accept阻塞,等待客戶端鏈接。在這時若是有個客戶端初始化一個Socket,而後鏈接服務器

      (connect),若是鏈接成功,這時客戶端與服務器端的鏈接就創建了。客戶端發送數據請求,

      服務器端接收請求並處理請求,而後把迴應數據發送給客戶端,客戶端讀取數據,最後關閉

      鏈接,一次交互結束

 

 

    

    服務端套接字函數

    s.bind() 綁定(主機,端口號)到套接字
    
    s.listen() 開始TCP監聽
    
    s.accept() 被動接受TCP客戶的鏈接,(阻塞式)等待鏈接的到來

    客戶端套接字函數

    s.connect() 主動初始化TCP服務器鏈接
    
    s.connect_ex() connect()函數的擴展版本,出錯時返回出錯碼,而不是拋出異常

    公共用途的套接字函數
    
    s.recv() 接收TCP數據
    
    s.send() 發送TCP數據(send在待發送數據量大於己端緩存區剩餘空間時,數據丟失,不會發完)
    
    s.sendall() 發送完整的TCP數據(本質就是循環調用send,sendall在待發送數據量大於己端緩存區剩餘空間時,數據不丟失,循環調用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() 建立一個與該套接字相關的文件

 

 

    使用socket來完成TCP通信

    應該先完成服務器的代碼編寫

 

    TCP 服務器 :

    

      import  socket

 

      # 1. 先建立一個表明服務器的socket對象

      s = socket.socket()

    

      # 2.  綁定ip地址與 端口號

      # 127.0.0.1  表示當前電腦的ip

      address = ('127.0.0.1',8090)          #傳入ip與端口

      s.bind((address))

      print ('服務器已啓動')

 

      #  3. 開始監聽這個端口

      #  參數5 表示能夠有五個處於半鏈接狀態的鏈接.(不是控制最大鏈接數的參數.)  

      s.listen(5)

 

      # 4. 接受鏈接請求

      # 該函數是阻塞的. 會卡主程序的執行,必須等到有一個客戶端進來纔會繼續執行.

      它會返回一個元組, 第一個表明客戶端的socket對象, 第二個是客戶端的端口

      client,c_address = s.accept()

      print('有一個鏈接已創建')

 

      # 5.讀寫數據

      # 接受數據 , 參數1024是須要接受的字節數

      res = client.recv(1024)

      print(res)

 

      # 6. 關閉鏈接

      s.close()    (通常不會關閉服務器.都是關閉客戶端)

      

 

 

 

    TCP 客戶端:

      import  socket

 

      # 1. 建立客戶端的socket對象

      c = socket.socket()

 

      # 2. 鏈接到服務器

      server_address = ('127.0.0.1',8080)    # 端口必須跟服務器同樣

    

      # 3.創建鏈接

      c.connect(server_address)

 

      # 4.讀寫數據

      # 發送數據到服務器

      c.send('hello 我是客戶端')

 

      # 5. 關閉鏈接

      c.close()

      

 

 

    使用socket來完成UDP通信,同樣是先建立服務端

 

    UDP 服務端:

    

      import  socket

      

      # 1.建立socket對象

      # 必須本身定義參數

      s = socket.socket(type = socket.SOCK_DGRAM)

 

      # 2. 綁定端口和ip

      s.bind(('127.0.0.1',10000))

 

      # 3. 接受數據. 接受數據的時候,沒有客戶端來鏈接,也會卡主,等待客戶端來鏈接了.再正常運行程序

      res = s.recv(1024)

      print(res)

 

      # 4. 

 

 

    UDP  客戶端 :

      import  socket

      

      # 1. 建立客戶端

      c = socket.socket(type = socket.SOCK_DGRAM)

 

      # 不須要鏈接, 能夠直接發送數據,只須要知道對方的ip和端口便可.

      c.sendto('這是UDP的客戶端'.encode('utf-8'),(127.0.0.1,10000))

 

      # 關閉客戶端

      c.close()

相關文章
相關標籤/搜索