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

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