day27-1 粘包问题、解决粘包问题

粘包问题

  • 只有TCP有粘包现象,UDP永远不会粘包

socket收发消息的原理

1580025-20190627184501173-357253379.png

在TCP协议中,如服务端向客户端传输数据:发送端是两K两K的发送数据,接收端是一K一K的发送数据,发送端将多余的的数据放在缓存中,接收端在取的时候会取到两条数据的部分。造成粘包问题

在UDP协议中,服务端向客户端传输数据:如发送端发送1025K的数据,而接收端只能接收1024K的数据,那多余的数据就会直接丢掉,下一条数据同理。所以UDP协议是不可靠传输,适用于传输小数据。不会有粘包问题

所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的

TCP发送数据的四种情况

假设客户端分别发送了两个数据包D1和D2给服务端,由于服务端一次读取到的字节数是不确定的,故可能存在以下4种情况。

1580025-20190627184522824-1680087824.png

  1. 服务端分两次读取到了两个独立的数据包,分别是D1和D2,没有粘包和拆包;
  2. 服务端一次接收到了两个数据包,D1和D2粘合在一起,被称为TCP粘包;
  3. 服务端分两次读取到了两个数据包,第一次读取到了完整的D1包和D2包的部分内容,第二次读取到了D2包的剩余内容,这被称为TCP拆包;
  4. 服务端分两次读取到了两个数据包,第一次读取到了D1包的部分内容D1_1,第二次读取到了D1包的剩余内容D1_2和D2包的整包。

粘包情况:两个数据非常小,然后间隔时间又短;数据太大,一次性取不完,下一次还会取这个大数据

解决粘包问题

解决粘包问题的原理:在传输数据之前,数据的大小必须得定长

服务端

import subprocess
import struct
from socket import *

server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 8000))
server.listen(5)
print('start...')

# 连接循环
while True:
    conn, client_addr = server.accept()

    # 通信循环
    while True:
        try:
            cmd = conn.recv(1024)
            print('来自客户端信息:', cmd)

            pipeline = subprocess.Popen(cmd.decode('utf8'),
                                        shell=True,
                                        stderr=subprocess.PIPE,
                                        stdout=subprocess.PIPE)
            stdout = pipeline.stdout.read()
            stderr = pipeline.stdout.read()

            byte_len = len(stdout) + len(stderr)
            guding_bytes = struct.pack('i', byte_len)

            conn.send(guding_bytes)
            conn.send(stdout+ stderr)

        except ConnectionResetError:
            break

客户端

import struct
from socket import *

client = socket(AF_INET, SOCK_STREAM)

client.connect(('127.0.0.1', 8000))

while True:
    cmd = input('please enter cmd>>>')
    client.send(cmd.encode('utf8'))

    guding_bytes = client.recv(4)
    data_len = struct.unpack('i', guding_bytes)[0]

    data = client.recv(data_len)
    print(data.decode('gbk'))

为何TCP是可靠传输,UDP是不可靠传输

  • TCP在数据传输时,发送端先把数据发送到自己的缓存中,然后协议控制将缓存中的数据发往对端,对端返回一个ack=1,发送端则清理缓存中的数据,对端返回ack=0,则重新发送数据,所以TCP是可靠的
  • udp发送数据,对端是不会返回确认信息的,因此不可靠

转载于:https://www.cnblogs.com/863652104kai/p/11098956.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值