06 ,tcp 粘包和拆包 :

1 ,粘包與拆包 : 發生的時機 ( tcp 協議 )

  1. 只有 tcp 協議出現粘包現象
  2. udp 協議是沒有的

2 ,粘包與拆包 : 什麼意思

  1. 發送端 :發數據
  2. 接收端 :不知道如何接受
  3. 後果 : 數據混亂

3 ,混亂 : 代碼

  1. 服務端 :
# Author:SFL
import socket
import subprocess

sk = socket.socket()
sk.bind(("127.0.0.1",8080))
sk.listen()
conn,addr = sk.accept()

while 1:
    cmd = conn.recv(1024).decode("utf-8")
    print(cmd)
    if cmd=="exit":
        break
    r = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    stdout = r.stderr.read()
    stderr = r.stdout.read()
    if stderr:
        conn.send(stderr.decode("gbk").encode("utf-8"))
    else:
        conn.send(stdout.decode("gbk").encode("utf-8"))

conn.close()
sk.close()
  1. 客戶端 :
# Author:SFL
import socket
import subprocess

sk = socket.socket()
sk.connect_ex(("127.0.0.1",8080))

while 1:
    cmd = input(">>>")
    sk.send(cmd.encode("utf-8"))
    res = sk.recv(1024).decode("utf-8")
    if res == "exit":
        break
    print(res)

sk.close()

4 ,混亂例子 : 操作

  1. 打開服務端
  2. 打開客戶端
  3. 客戶端發送命令 :
    1 ,ipconfig
    2 ,ls
  4. 現象 : 由於 ipconfig 命令回覆的消息內容較多,導致下一次的命令中,出現了上次應該出現的內容

5 ,混亂 :原因

客戶端的緩衝區大小不夠

6 ,混亂 : 解決

  1. 思路 : 調整緩衝區大小
  2. 精華代碼 : 將緩衝區大小變大
res = sk.recv(102400).decode("utf-8")

7 ,粘包 : 經典例子

  1. 客戶端 :發送數據
    發送 hello 和 world :
sk.send(b"hello")
sk.send(b"world")
  1. 服務端端 : 接收數據
conn.recv(1024)
conn.recv(1024)
  1. 正常情況 :
hello
world
  1. 特殊情況 : 粘包
"helloworld"
""

8 ,拆包 :

  1. MTU :網卡上限 ( 網絡傳輸的最大數據包 )
  2. 超限拆包 :當 tcp 的緩衝區大於 MTU 上限時,在網絡傳輸中,就會把數據包拆解

9 ,粘包 :

  1. 根本原因 : 緩衝區大於數據量大小
  2. 發生的機率 : 不大
  3. 內部原理 : 一個包,兩條消息
    服務端一共就讀到一個數據包,這個數據包包含客戶端發出的兩條消息的完整信息,這個時候基於之前邏輯實現的服務端就蒙了,因爲服務端不知道第一條消息從哪兒結束和第二條消息從哪兒開始,這種情況其實是發生了TCP粘包。

10 ,tcp 與 udp 機制 : 年報比較

  1. tcp :有可能粘包
  2. udp:沒可能粘包

11 ,粘包的兩種情況 :

  1. 發送方緩衝機制 : 發送端需要等緩衝區滿才發送消息,造成粘包
    ( 請求時間間隔短,每次發送的數據量小 )
  2. 接收方緩衝機制 : 接收方接收數據不及時,造成多個包被遺棄接收

12 ,粘包,拆包問題的解決方案

  1. tcp 無界 : tcp是無界的數據流
  2. 無法從底層解決 : 協議本身無法避免粘包,拆包的發生
  3. 只能從應用層解決 : 只能在應用層數據協議上,加以控制
  4. 例如 : 使用帶消息頭的協議、消息頭存儲消息開始標識及消息長度信息,服務端獲取消息頭的時候解析出消息長度,然後向後讀取該長度的內容。

13 ,解決粘包問題的實例 :

  1. 我的另一篇博客網址 : 文件上傳例子
  2. https://blog.csdn.net/qq_34319644/article/details/106235226

14 ,緩衝區大小設置多少合適 :

https://my.oschina.net/hejunbinlan/blog/1526871

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章