Python網絡編程(socket模塊、緩沖區、http協議)


 

 
網絡的概念:主機   端口  IP  協議
  •           服務器:
  •       localhost/127.0.0.1
  •   客戶端:
  •       只是在本機啟動客戶端,用127.0.0.1訪問
 
 
  •   服務器:
  •       0.0.0.0
  •   客戶端:
  •       可以在本機用127.0.0.1、192.168.0.1
 
  •   服務器:
  •       192.168.0.1
  •   客戶端:
  •       局域網內用192.168.0.1
 
 
socket(創建套接字) --->  bind(綁定地址) --->  listen(設置監聽)--->  accept(等待鏈接) --->  recv/send(收/發消息) --->  close ()
 
 
 
收發函數特性:
      recv特征:
  1. 如果建立的另一端鏈接被斷開, 則recv立即返回空字符串
  2. recv接受緩沖區取出內容,當緩沖區為空則阻塞
  3. recv如果一次接受不完緩沖區的內容下次執行會自動接受
      send特征:
  1.         如果發送的另一端不存在則會產生Pipe Broken異常
  2. send發送緩沖區發送內容,緩沖為滿則堵塞
 
網絡的收發緩存區:
     在內存中開辟區域,用於 發送和接受的緩沖
     作用:
  1.         協調數據的收發(接受和處理速度
  2.         減少磁盤的交互
sendall(date):
   功能: tcp套接字發送消息
   參數:同 send
   返回值:如果 發送成功返回None    否則返回異常
 
 
tcp粘包:
    產生原因:
        1. tcp傳輸以 字節流的方式 發送消息, 消息之間沒有邊界
2.發送比 接受的速度快
   影響:
        對每次發送的內容是一個獨立的意識需要單獨識別時 容易使用原文件被更改
    如何處理:
        1.每次發送后 追加一個結尾標志,代表本次發送完畢
2. 發送一個 數據結構
3. 每次發送有一個 時間間隔
 
基於udp的服務端編程:
     1.創建套接字:
        sockfd = socket(AF_INET,SOCK_DGRAM)
     2.綁定地址:
        sockfd.bind()
     3.消息收發
        data, addr = sockfd. recvfrom(buffersize)
         功能:接受udp消息
 參數:接受消息的大小
 返回值:
      data 接受到的內容
      addr 消息發送的地址
        
recvfrom每次接受一個報文, 如果沒有接受到的內容則直接丟棄
        sockfd. sendto(data, addr)
  功能:udp消息發送
  參數:
      data 要發送的內容 bytes
      addr 目標地址
  返回:發送字節數
     4.關閉套接字:
        socket.close()
 
 
import  sys
    sys.argv
   作用:
      獲取從命令行獲取的參數內容
       Python3 demo.py 參數1, 參數2.....
 
       sys.argv[0] 是命令本身(程序本身)
 
 
tcp流式套接字和udp數據報套接字區別:
  •     1.流式套接字采用字節流的方式進行傳輸,
  •        而數據報套接字使用數據報形式傳輸數據
  •     2.tcp套接字會產生粘包,udp不會
  •     3.tcp編程可以保證消息的完整性,udp則不一定
  •     4.tcp需要listen、accept、udp不用
  •     5.tcp消息的發送接收使用recv、send、sendall、
  •        udp使用recvfrom,sendto
 
 
 
socket模塊套接字屬性(s為套接字)
  •   s.type:表示套接字類型
  •   s.family地址類型
 
   套接字屬性方法
     s.fileno()
     功能:
        獲取套接字的 文件描述符
   文件描述符:
     每一個IO事件 操作系統都會分配一個不同的的正整數,
     該正整數即為此IO操作的文件描述符
      默認開啟的描述符:
  1.          sys.stdin      0
  2.          sys.stdout   1
  3.          sys.stderr    2
 
  s.getsockname()
     功能:
        獲取套結字綁定 的地址
  s. getpeername()
     功能:
        獲取鏈接套接字 客戶端的地址
  s.setsockopt(level,optname, value)
       (#  設置端口可立即重用 必須在鏈接端口前設置
        s.setsockopt(SOL_SOcKET, SO_REUSEADDR))
     功能:設置套接字選項
     參數:
        level:設置 選項的類型(大類型)  常用:SOL_SOCKET
optname: 子類選項
value: 要設置的值
 
   s.getsockoptlevel , optname)
     功能: 獲取套接字選項值
     參數:
        level:選項的類型
 
udp套接字應用--->   廣播
    一點發送多點接收
     目標地址:廣播地址 172.18.32 .255
 
 
tcp應用---> http傳輸
 
http協議:
   超文本傳輸協議
    用途:
      網站中瀏覽器 網頁的獲取,基於 網站事物 數據傳輸
      編寫基於http協議的 數據傳輸
    特點:
      1. 應用層協議,傳輸層使用tcp服務
      2. 簡單、靈活,可以使用 多種編程語言操作
      3.無狀態的協議,既不用記錄用戶的輸入內容
      4. http1.1  ---> http2.0(還沒發布)   技術的成熟和穩定性
    http請求(request):
       請求格式:
          1.請求行:說明具體的 請求類別和內容
          GET    /index.html    /HTTP/1.1
                請求類別   請求內容    協議版本
      請求類別:
  1. GET:              獲取網絡資源
  2. POST:           提交一定的附加數據
  3. HEAD:          獲取響應頭
  4. PUT:             更新服務器資源
  5. DELETE:        刪除服務器資源
  6. CONNECT:   未使用
  7. TRACE:         用於測試
  8. OPTIONS:    獲取服務器性能信息
 
  2.請求頭:請求的具體描述
     Accept:text/html
         每一個鍵值對占一行,描述了一個特定信息
  3.空行
 4.請求體: 具體參數或提交的 內容
     get參數或者post提交的內容
    http響應(response):
       響應格式:
          1.響應行: 反饋具體的 響應情況
          HTTP/1.1     20       OK
  版本協議   響應碼   附加信息
     響應碼:
  1.        1xx:提示信息,表示請求已接收
  2.        2xx:響應成功
  3.        3xx:響應需要定向(重新記載鏈接第三方鏈接)
  4.        4xx:客戶端錯誤
  5.        5xx:服務器端錯誤
     常見響應碼:
      200  成功
      404  請求 內容不存在
      401  沒有訪問 權限
      500  服務器 未知錯誤
      503   服務器暫時 無法執行
       2.響應頭:對響應 內容的具體描述
      3.空行
      4.響應體:
          將客戶端請求內容進行返回
 

 
 
 
 
這里這個圖就看了一眼 沒特意去記  憑印象畫的  可能不對 但是大體邏輯應該沒錯 
我去百度搜了 什么也沒搜到 不知道是不是我的打開方式不對還是什么
只搜到了上面的兩張圖..........
 
總結:
tcp,udp協議的區別和編程實現上的差異:
          tcp:
  •                tcp是一種可靠的、面向有鏈接數據傳輸服務
  •                tcp能夠保證數據的完整性、順序性、無重復以及無差錯
  •                tcp是一種以文件流的形式傳輸數據的服務 文件流之間是沒有邊界
  •                的所以基友可能會產生粘包的情況 粘包是因為接受速度沒有傳輸速度快
  •                導致緩存區的數據擁堵 下次取出數據時從而產生非獨立數據的鏈接 這種情況
  •                叫做粘包  粘包只有傳輸多個數據時才會出現
  •                tcp的編程需要監聽套接字 和 等待鏈接過程 只有鏈接成功才能發送數據
  •                這種情況叫做三次握手、還有斷開時的四次揮手
  •                三次揮手:客戶端請求鏈接、服務器返回報文、客戶端完成鏈接
  •                四次揮手:客戶端請求斷開、服務器接受請求、服務器准備完畢可以斷開、客戶端斷開
  •                tcp收發送消息需要使用recv、send、sendall方法
  •                sendall比特殊 功能和send一樣 但sendall有事務  若發送成功返回None 否則觸發異常
  •               鏈接時必須先運行服務器端后運行客戶端
         udp:
  •              udp就比較簡單了  是面向無連接的不可靠的數據傳輸服務
  •              udp沒有數據流  接受大小取決於接收方
  •              若數據超出接收方接受范圍則丟掉所有超出范圍的內容
  •              udp不存在粘包的情況
  •              udp不需要等待鏈接 沒有揮手過程 先發就發 想收就收 自由度比較高
  •              udp編程時收發消息使用recvfrom、sendto方法
  •              udp可用於廣播可以隨時斷開或鏈接
  •              客戶端和服務器端可以隨時運行
 
什么是http?
 
       http 是超文本傳輸協議
               一種網絡數據傳輸的協議
              沒錯就是  協議
             並且所有的www文件都必須遵守這個標准
http作用是什么?
 
      可以用力來網站中瀏覽器網頁獲取,基於網站上的一些數據傳輸 例如目前我正在打的字......
      編寫基於http協議的數據傳輸  
 
http協議 請求和響應的格式以及每一部分做什么
      請求部分:
               請求行:請求的具體類別和內容   比如說  類別、內容、版本協議
               請求頭:請求具體描述
               空行:就是空行
               請求體:請求具體參數或內容
      響應部分:
               響應行:具體響應情況     比如說  版本協議 、響應碼 、附加信息  
               響應頭:響應具體描述
               空行
               響應體:響應具體參數或內容
http協議中請求的基本類型和作用:
        GET:獲取網絡資源
        POST:提交一定的附加數據
        HEAD:獲取響應頭 響應返回的文件信息
        PUT:更新服務器資源
        DELETE:刪除服務器資源
        TRACE:用於測試
         OPIONS:獲取服務器性能信息
        CONNECT:備用
http協議響應碼的類型和表達含義:
          以1開頭的表示請求已經鏈接
          以2開頭的表示成功接收、提示
          以3開頭的代表重新定向進一步處理 第三方
          以4開頭的客戶端錯誤
          以5開頭的服務器錯誤
http協議請求網頁的流程:
           建立連接、發送請求、響應請求、斷開鏈接
           這樣的一個過程稱為一個事物
           
 
 文件傳輸示例:
服務器端
from socket import *
from time import sleep 

s = socket()

s.bind(('0.0.0.0',8888))
s.listen(5)

c,addr = s.accept()
print("Connect from ",addr)

f = open('img.jpg','rb')
#將文件名稱告知對方
c.send('img.jpg'.encode())
sleep(0.1)

while True:
    data = f.read(1024)
    if not data:
        break
    c.send(data)
    
sleep(0.1)
c.send('##'.encode())

data = c.recv(1024)
print(data.decode())

f.close()
c.close()
s.close()

 

客戶端

from socket import * 

s = socket()

s.connect(('172.60.50.181',8888))

filename = s.recv(1024).decode()

f = open('/home/tarena/'+filename,'wb')

while True:
    data = s.recv(1024)
    if data == b'##':
        break
    f.write(data)

s.send("接收完成".encode())

f.close()
s.close()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM