python入门开发学习笔记之粘包现象与解决方案

TCP通信传输数据粘包问题及解决方法 问题背景: 利用TCP协议传输json格式数据,json格式数据是以大括号 {} 开始和结束的,(此处当然也可以是其他格式的数据),会产生粘包问题,粘包的现象是每次发送的数据要么不完整、要么冗余,由于json格式的数据解析对格式要求非常严格,必须是单个完整的json字符串,多一点都不行。所以解决粘包带来的问题是必须的。 解决方法: 发送端:在每个json字符串的开头,添加一个报头,报头中隐藏着该json字符串的长度; 接收端:设立一个缓存区,将接收到的数据全部存到缓存区中,利用缓存区的size和j 阅读详情

本节重点:

  • 使学生了解粘包原理
  • 让学生掌握粘包解决方案

本节时长需控制在70-80分钟内

简单远程执行命令程序开发(30分钟)

是时候用户socket干点正事呀,我们来写一个远程执行命令的程序,写一个socket client端在windows端发送指令,一个socket server在Linux端执行命令并返回结果给客户端

执行命令的话,肯定是用我们学过的subprocess模块啦,但注意注意注意:

res = subprocess.Popen(cmd.decode('utf-8'),shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)

命令结果的编码是以当前所在的系统为准的,如果是windows,那么res.stdout.read()读出的就是GBK编码的,在接收端需要用GBK解码,且只能从管道里读一次结果

ssh server

import socket
import subprocess

ip_port = ('127.0.0.1', 8080)

tcp_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_socket_server.bind(ip_port)
tcp_socket_server.listen(5)

while True:
    conn, addr = tcp_socket_server.accept()
    print('客户端', addr)

    while True:
        cmd = conn.recv(1024)
        if len(cmd) == 0: break
        print("recv cmd",cmd)
        res = subprocess.Popen(cmd.decode('utf-8'), shell=True,
                               stdout=subprocess.PIPE,
                               stdin=subprocess.PIPE,
                               stderr=subprocess.PIPE)

        stderr = res.stderr.read()
        stdout = res.stdout.read()
        print("res length",len(stdout))
        conn.send(stderr)
        conn.send(stdout)

ssh client

import socket
ip_port = ('127.0.0.1', 8080)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
res = s.connect_ex(ip_port)

while True:
    msg = input('>>: ').strip()
    if len(msg) == 0: continue
    if msg == 'quit': break

    s.send(msg.encode('utf-8'))
    act_res = s.recv(1024)

    print(act_res.decode('utf-8'), end='')

尝试执行ls、pwd命令,你惊喜的发现,拿到了正确的结果!

but 莫开心太早,此时执行一个结果比较长的命令,比如top -bn 1, 你发现依然可以拿到结果,但如果再执行一条df -h的话,就发现,你拿到并不是df命令的结果,而是上一条top命令的部分结果。为啥捏?为啥捏?为啥捏?

是因为,top命令的结果比较长,但客户端只recv(1024), 可结果比1024长呀,那怎么办,只好在服务器端的IO缓冲区里把客户端还没收走的暂时存下来,等客户端下次再来收,所以当客户端第2次调用recv(1024)就会首先把上次没收完的数据先收下来,再收df命令的结果。

那怎么解决呢? 有些同学说,直接把recv(1024)改大不就好了,改成5000\10000或whatever. 可我的亲,这么干的话,并不能解决实际问题,因为你不可能提前知道对方返回的结果数据大下,无论你改成多大,对方的结果都有可能比你设置的大,另外这个recv并不是真的可以随便改特别大的,有关部门建议的不要超过8192,再大反而会出现影响收发速度和不稳定的情况

同志们,这个现象叫做粘包,就是指两次结果粘到一起了。它的发生主要是因为socket缓冲区导致的,来看一下

[图片上传失败…(image-42662d-1651241814414)]

你的程序实际上无权直接操作网卡的,你操作网卡都是通过操作系统给用户程序暴露出来的接口,那每次你的程序要给远程发数据时,其实是先把数据从用户态copy到内核态,这样的操作是耗资源和时间的,频繁的在内核态和用户态之前交换数据势必会导致发送效率降低, 因此socket 为提高传输效率,发送方往往要收集到足够多的数据后才发送一次数据给对方。若连续几次需要send的数据都很少,通常TCP socket 会根据优化算法把这些数据合成一个TCP段后一次发送出去,这样接收方就收到了粘包数据。

粘包问题只存在于TCP中,Not UDP

还是看上图,发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream),一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因。而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和TCP是很不同的。怎样定义消息呢?可以认为对方一次性write/send的数据为一个消息,需要明白的是当对方send一条信息的时候,无论底层怎样分段分片,TCP协议层会把构成整条消息的数据段排序完成后才呈现在内核缓冲区。

例如基于tcp的套接字客户端往服务端上传文件,发送时文件内容是按照一段一段的字节流发送的,在接收方看了,根本不知道该文件的字节流从何处开始,在何处结束

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

总结

  1. TCP(transport control protocol,传输控制协议)是面向连接的,面向流的,提供高可靠性服务。收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制。 即面向流的通信是无消息保护边界的。
  2. UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务。不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。 即面向消息的通信是有消息保护边界的。
  3. tcp是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住,而udp是基于数据报的,即便是你输入的是空内容(直接回车),那也不是空消息,udp协议会帮你封装上消息头,实验略
基于UDP的命令执行程序(10分钟)

上面说了,udp不存在粘包问题,我们看一下实例

udp server

import socket
import subprocess

ip_port = ('127.0.0.1', 9003)
bufsize = 1024

udp_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_server.bind(ip_port)

while True:
    # 收消息
    cmd, addr = udp_server.recvfrom(bufsize)
    print('用户命令----->', cmd,addr)

    # 逻辑处理
    res = subprocess.Popen(cmd.decode('utf-8'), shell=True, stderr=subprocess.PIPE, stdin=subprocess.PIPE,
                           stdout=subprocess.PIPE)
    stderr = res.stderr.read()
    stdout = res.stdout.read()

    # 发消息
    udp_server.sendto(stdout + stderr, addr)

udp_server.close()

udp client

from socket import *

import time

ip_port = ('127.0.0.1', 9003)
bufsize = 1024

udp_client = socket(AF_INET, SOCK_DGRAM)

while True:
    msg = input('>>: ').strip()
    if len(msg) == 0:
        continue

    udp_client.sendto(msg.encode('utf-8'), ip_port)
    data, addr = udp_client.recvfrom(bufsize)
    print(data.decode('utf-8'), end='')

粘包的解决办法(35分钟)

问题的根源在于,接收端不知道发送端将要传送的字节流的长度,所以解决粘包的方法就是围绕,如何让发送端在发送数据前,把自己将要发送的字节流总大小让接收端知晓,然后接收端来一个死循环接收完所有数据

普通青年版

服务器端

import socket,subprocess
ip_port=('127.0.0.1',8080)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

s.bind(ip_port)
s.listen(5)

while True:
    conn,addr=s.accept()
    print('客户端',addr)
    while True:
        msg=conn.recv(1024)
        if not msg:break
        res=subprocess.Popen(msg.decode('utf-8'),shell=True,\
                            stdin=subprocess.PIPE,\
                         stderr=subprocess.PIPE,\
                         stdout=subprocess.PIPE)
        err=res.stderr.read()
        if err:
            ret=err
        else:
            ret=res.stdout.read()
        data_length=len(ret)
        conn.send(str(data_length).encode('utf-8'))
        data=conn.recv(1024).decode('utf-8')
        if data == 'recv_ready':
            conn.sendall(ret)
    conn.close()

客户端

import socket,time
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
res=s.connect_ex(('127.0.0.1',8080))

while True:
    msg=input('>>: ').strip()
    if len(msg) == 0:continue
    if msg == 'quit':break

    s.send(msg.encode('utf-8'))
    length=int(s.recv(1024).decode('utf-8'))
    s.send('recv_ready'.encode('utf-8'))
    send_size=0
    recv_size=0
    data=b''
    while recv_size < length:
        data+=s.recv(1024)
        recv_size+=len(data) #为什么不直接写1024?

    print(data.decode('utf-8'))

为何low?

程序的运行速度远快于网络传输速度,所以在发送一段字节前,先用send去发送该字节流长度,这种方式会放大网络延迟带来的性能损耗

刚才上面 在发送消息之前需先发送消息长度给对端,还必须要等对端返回一个ready收消息的确认,不等到对端确认就直接发消息的话,还是会产生粘包问题(承载消息长度的那条消息和消息本身粘在一起)。 有没有优化的好办法么?

文艺青年版一

思考一个问题,为什么不能在发送了消息长度(称为消息头head吧)给对端后,立刻发消息内容(称为body吧),是因为怕head 和body 粘在一起,所以通过等对端返回确认来把两条消息中断开。

可不可以直接发head + body,但又能让对端区分出哪个是head,哪个是body呢?我靠、我靠,感觉智商要涨了。

想到了,把head设置成定长的呀,这样对端只要收消息时,先固定收定长的数据,head里写好,后面还有多少是属于这条消息的数据,然后直接写个循环收下来不就完了嘛!唉呀妈呀,我真机智。

可是、可是如何制作定长的消息头呢?假设你有2条消息要发送,第一条消息长度是 3000个字节,第2条消息是200字节。如果消息头只包含消息长度的话,那两个消息的消息头分别是

len(msg1) = 4000 = 4字节
len(msg2) = 200 = 3字节

你的服务端如何完整的收到这个消息头呢?是recv(3)还是recv(4)服务器端怎么知道?用尽我所有知识,我只能想到拼接字符串的办法了,打比方就是设置消息头固定100字节长,不够的拿空字符串去拼接。

server

import socket,json
import subprocess

ip_port = ('127.0.0.1', 8080)

tcp_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_socket_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #一行代码搞定,写在bind之前
tcp_socket_server.bind(ip_port)
tcp_socket_server.listen(5)

def pack_msg_header(header,size):
    bytes_header = bytes(json.dumps(header),encoding="utf-8")
    fill_up_size = size -  len(bytes_header)
    print("need to fill up ",fill_up_size)

    header['fill'] = header['fill'].zfill(fill_up_size)
    print("new header",header)
    bytes_new_header = bytes(bytes(json.dumps(header),encoding="utf-8"))
    return bytes_new_header

while True:
    conn, addr = tcp_socket_server.accept()
    print('客户端', addr)

    while True:
        cmd = conn.recv(1024)
        if len(cmd) == 0: break
        print("recv cmd",cmd)
        res = subprocess.Popen(cmd.decode('utf-8'), shell=True,
                               stdout=subprocess.PIPE,
                               stdin=subprocess.PIPE,
                               stderr=subprocess.PIPE)

        stderr = res.stderr.read()
        stdout = res.stdout.read()
        print("res length",len(stdout))

        msg_header = {
            'length':len(stdout + stderr),
            'fill':''
        }
        packed_header = pack_msg_header(msg_header,100)
        print("packed header size",packed_header,len(packed_header))
        conn.send(packed_header)
        conn.send(stdout + stderr)

client

import socket
import json

ip_port = ('127.0.0.1', 8080)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
res = s.connect_ex(ip_port)

while True:
    msg = input('>>: ').strip()
    if len(msg) == 0: continue
    if msg == 'quit': break

    s.send(msg.encode('utf-8'))
    response_msg_header = s.recv(100).decode("utf-8")

    response_msg_header_data = json.loads(response_msg_header)
    msg_size = response_msg_header_data['length']

    res = s.recv(msg_size)
    print("received res size ",len(res))
    print(res.decode('utf-8'), end='')

文艺青年版二

为字节流加上自定义固定长度报头也可以借助于第三方模块struct,用法为

import json,struct
#假设通过客户端上传1T:1073741824000的文件a.txt

#为避免粘包,必须自定制报头
header={'file_size':1073741824000,'file_name':'/a/b/c/d/e/a.txt','md5':'8f6fbf8347faa4924a76856701edb0f3'} #1T数据,文件路径和md5值

#为了该报头能传送,需要序列化并且转为bytes
head_bytes=bytes(json.dumps(header),encoding='utf-8') #序列化并转成bytes,用于传输

#为了让客户端知道报头的长度,用struck将报头长度这个数字转成固定长度:4个字节
head_len_bytes=struct.pack('i',len(head_bytes)) #这4个字节里只包含了一个数字,该数字是报头的长度

#客户端开始发送
conn.send(head_len_bytes) #先发报头的长度,4个bytes
conn.send(head_bytes) #再发报头的字节格式
conn.sendall(文件内容) #然后发真实内容的字节格式

#服务端开始接收
head_len_bytes=s.recv(4) #先收报头4个bytes,得到报头长度的字节格式
x=struct.unpack('i',head_len_bytes)[0] #提取报头的长度

head_bytes=s.recv(x) #按照报头长度x,收取报头的bytes格式
header=json.loads(json.dumps(header)) #提取报头

#最后根据报头的内容提取真实的数据,比如
real_data_len=s.recv(header['file_size'])
s.recv(real_data_len)

使用struct模块实现方式如下

server

import socket,struct,json
import subprocess
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加

phone.bind(('127.0.0.1',8080))

phone.listen(5)

while True:
    conn,addr=phone.accept()
    while True:
        cmd=conn.recv(1024)
        if not cmd:break
        print('cmd: %s' %cmd)

        res=subprocess.Popen(cmd.decode('utf-8'),
                             shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        err=res.stderr.read()
        print(err)
        if err:
            back_msg=err
        else:
            back_msg=res.stdout.read()

        headers={'data_size':len(back_msg)}
        head_json=json.dumps(headers)
        head_json_bytes=bytes(head_json,encoding='utf-8')

        conn.send(struct.pack('i',len(head_json_bytes))) #先发报头的长度
        conn.send(head_json_bytes) #再发报头
        conn.sendall(back_msg) #在发真实的内容

    conn.close()

client

from socket import *
import struct,json

ip_port=('127.0.0.1',8080)
client=socket(AF_INET,SOCK_STREAM)
client.connect(ip_port)

while True:
    cmd=input('>>: ')
    if not cmd:continue
    client.send(bytes(cmd,encoding='utf-8'))

    head=client.recv(4) #先收4个bytes,这里4个bytes里包含了报头的长度
    head_json_len=struct.unpack('i',head)[0] #解出报头的长度
    head_json=json.loads(client.recv(head_json_len).decode('utf-8')) #拿到报头
    data_len=head_json['data_size'] #取出报头内包含的信息

    #开始收数据
    recv_size=0
    recv_data=b''
    while recv_size < data_len:
        recv_data+=client.recv(1024)
        recv_size=len(recv_data)

    print(recv_data.decode('utf-8'))
    #print(recv_data.decode('gbk')) #windows默认gbk编码
小甲鱼《零基础入门学习Python》学习笔记 根据老师的建议,现在将第二次复习小甲鱼的《零基础入门学习Python》而做的学习笔记,上传到网上,方便今后复习和保存,因为是手写的,所以做了扫描锐化处理,方便阅读。 ... 阅读详情

相关推荐

粘包现象及解决方法(Python)

粘包现象及解决方法(Python) 什么是粘包 只有TCP有粘包现象,UDP没有 socket收发消息的原理 应用程序看到的数据是一个整体,或称为一个流(stream),而一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议。 而UDP协议是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据。 而消息可以认为发送方一次性write/send的数据为一个消息...

Licasaxi的博客 1138

python are you ready_如果要检查recv_ready(),是否必须检查exit_status_ready?

也就是说,在等待recv_ready()数据准备就绪之前,我真的要先检查退出状态吗?不。从远程进程接收数据(例如stdout/stderr)是完全正确的,即使它还没有完成。另外,一些sshd实现甚至不提供远程进程的退出状态,在这种情况下,您将遇到问题,请参见paramiko doc: exit_status_ready。等待exit_status_code短生命远程命令的问题是,本地线程接收退出代...

weixin_39875832的博客 1950

《Python全栈开发:Python TCP 粘包现象》

一、粘包现象 只有TCP有粘包现象,UDP永远不会粘包 发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream),一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因。而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和

yexiang优快云的专栏 2278

Python实现类似expect脚本的远程交互式编程实现自动化需求

需求说明 通过python代码来实现类似expect shell的交互式能力,这样在python代码中能结合业务逻辑组装代码,具有比expect更强大的自动化处理能力。 如果能通过该交互能力,结合SFTP来实现文件相关的操作,那就更加的强大了。 该篇文章代码为交互式命令封装实现。 实现 依赖 依赖paramiko库,所以需要执行pip install paramiko来安装。 代码封装实现 import time import paramiko from paramiko import SSHClient

白杨 1974

json粘包处理 [Delphi]

本demo演示了 多个json包粘在一起的处理方法,用到了第三方库 QDAC

c语言的json连续解析,主要姐姐粘包

C语言的json解析,主要用于处理粘包; 将连续的多包json数据拆解成json链表~

python网络通信编程_python之网络编程

1.OSI协议与TCP/IP协议OSI是Open System Interconnection的缩写,意为开放式系统互联。国际标准化组织(ISO)制定了OSI模型,该模型定义了不同计算机互联的标准,是设计和描述计算机网络通信的基本框架。OSI模型把网络通信的工作分为7层,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。这是一种事实上被TCP/IP 4层模型淘汰的协议。在当今世界上...

weixin_39692271的博客 319

(RegionProposal Network)RPN网络结构及详解

RPN(RegionProposal Network)区域生成网络 Faster-RCNN的核心。在这里整理。 1.anchors。 特征可以看做一个尺度51*39的256通道图像,对于该图像的每一个位置,考虑9个可能的候选窗口:三种面积{128,256,512}×{128,256,512}×三种比例{1:1,1:2,2:1}{1:1,1:2,2:1}。这些候选窗口称为anchors...

凹酱的DEEP LEARNING 19万+

golang中解决tcp传输中的粘包问题

golang中解决tcp传输中的粘包问题 Author: 岳东卫 Email: usher.yue@gmail.com 什么是粘包? 最近在写https://github.com/UsherYue/ActivedRouter (一个http/https反向代理服务)的时候遇到了粘包问题, 如果有做过网络编程的小伙伴应该都...

weixin_33836874的博客 745

kaggle:Digit Recognizer《手写数字识别》你的第一个图像识别竞赛项目

新手,入门,巩固复习,深度学习,图像识别

qq_63591092的博客 3097

主成分分析(Principal Component Analysis,PCA)

主成分分析1.主成分分析1.1 降维(Dimensionality Reduction)1.2 均值(Mean)1.3 方差(Variance)1.4 协方差(Covariance)1.5 协方差矩阵(Covariance Matrix)1.6 线性变换(Linear Transformation)1.7 主成分分析(PCA)1.8 PCA和SVD的关系 1.主成分分析 关于PCA的介绍:用最直观的方式告诉你:什么是主成分分析PCA 笔记来源:Principal Component Analysis (PC

一个搬运知识的笨小孩 3230

粘包现象

粘包现象 当多条消息发送时接受变成了一条或者出现接收不准确的情况 粘包现象会发生在发送端 两条消息间隔时间短,长度短 就会把两条消息在发送之前就拼在一起 节省每一次发送消息回复的网络资源 粘包现象会发生在接收端 多条消息发送到缓存端,但没有被及时接收,或者接收的长度不足一次发送的长度 数据与数据之间没有边界 本质 : 发送的每一条数据之间没有边界 – 例: import socket sk = ...

Lyji 227

SAC-IA算法点云粗配准

SAC-IA(Sample Consensus Initial Alignment)是PCL库中的一种初始点云配准算法,它使用特征匹配和RANSAC(随机抽样一致性)框架来估计两个点云之间的初始刚性变换。其目标是通过特征描述符找到一组可靠的匹配点对,并使用这些点对估计初始对齐的变换矩阵。

twnkie的博客 1445

【Python开发】Python入门

摘要:从基础到实践的全面学习路径 本文系统介绍了Python编程语言的学习路线,涵盖五大核心内容: 选择Python的优势:简单易学、应用广泛(AI/数据分析/Web开发)、丰富库资源和活跃社区 基础入门:安装配置、第一个程序、变量与数据类型(整型/浮点/字符串/布尔值) 基本语法:算术/比较/逻辑运算符,条件语句和循环结构 函数与模块:定义使用函数、导入标准库和第三方模块 实践拓展:通过简易计算器项目巩固知识,并推荐菜鸟教程、官方文档等优质学习资源 文章以实例驱动讲解,强调实践应用,适合零

大雨淅淅的博客 3891

华为eNSP镜像包全集下载,包含CE6800、CE12800、NE系列等!

你好,这里是网络技术联盟站。昨天给大家介绍了win11、10下安装eNSP最新系列(1.3.00)并完美运行,附下载。从文章发布到发文前,一直有朋友想让瑞哥提供一下华为ENSP镜像包,今天安排!eNSP安装包、以及eNSP中所需要的镜像包(设备包)(CE、CX、NE40E、NE5000E、NE9000、USG)例如:导入一个USG设备包,eNSP中的USG5500和USG6000V都是可以启动的。如果你的报错“40”的话,那么打开Oracle VM VirtualBox这个虚拟机,删除对应报错的虚拟机,然后

网络技术联盟站 3万+

YOLOv9原创自研:卷积魔改 | 一种新颖的风车形卷积(PConv)融合注意力机制,加强微弱小目标检测能力

为了进一步提升小目标检测能力,风车形卷积(PConv)融合注意力机制进一步提升小目标检测能力

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 362

python之粘包现象

文章目录1、粘包现象1.1、什么是粘包1.2、粘包的两种情况1.2.1、方式一1.2.2、方式二1.3、解决远程执行命令粘包问题1.4、定制复杂的报头(拷贝文件) 1、粘包现象 1.1、什么是粘包 只有TCP有粘包现象,UDP永远不会粘包 粘包不一定会发生 如果发生了: 1.可能是在客户端已经粘了 2.客户端没有粘,可能是在服务端粘了 socket收发消息的原理 应用程序所看到的数据是一个整体,或说是一个流(stream),一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出

一切随心走的博客 702

Trae 在代码审查场景的 3 大差异化能力:对比 Claude Code、Cursor 与 Codex 实测

揭示代码审查的核心矛盾是上下文断层而非找 Bug,介绍 Trae 通过跨文件符号追踪、意图-实现对齐校验、增量变更影响图谱生成三件事实现上下文校准,并对比其与 Claude Code、Cursor、Codex 在多模块 Java 项目中的实际审查差异

weixin_42525482的博客 152

Python Gstreamer入门-学习笔记

Python Gstreamer入门-学习笔记   历时一个月的Python Gstreamer入门阶段接近尾声,在这里总结一下自己的学习历程。首先感谢一下Andy同学和Stephen老师的帮助和指导。 1.基础知识学习阶段   首先需要了解Gstreamer是什么,有哪些基本的内容,element、pad、bin、pipeline各是什么,其中又有哪些分类。这里推荐Gsteamer的官方文档进行...

小平爱吃肉的博客 1万+

【AI编程】Vibe Coding 开发环境搭建与项目实战操作详解

Vibe Coding 开发环境搭建与项目实战操作详解

congge 7335

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

网络通信与并发编程(三)粘包现象解决方案、socketserver实现并发

有了上一篇文章的分析,我们知道tcp协议之所以会出现粘包现象,是因为无法得知每次传输的字节数。如果我们人为的给传输的数据添加一个报头用来表示接收内容的字节数就可以解决这个问题了。映像名称 PID 会话名 会话# 内存使用。映像名称 PID 会话名 会话# 内存使用。(接收内容过长,中间部分略去)(接收内容过长,中间部分略去)

m0_45491627的博客 679

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

python之粘包现象与解决

今日单词 socket 插座 套接字 少开的 phone 手机 server 服务器 少我 bind 捆绑 client客户 可来嗯 accept 接受 阿婆晒的 addr conn connect 接受 recv 接收 send 发送 decode解码 encode编码 total 全部的 偷偷 size 大小 塞子 result 结果 内稍ci ipconfig 微软操作系统中的...

weixin_30917213的博客 153

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

python--subprocess,粘包现象与解决办法,缓冲区

一. subprocess 的简单用法 import subprocess sub_obj = subprocess.Popen( 'dir', #系统指令 shell=True, #固定方法 stdout=subprocess.PIPE, #标准输出 PIPE 管道,保存着指令的执行结果 stderr=subprocess.PI...

dianlamu4982的博客 493

【C语言与Python学习笔记目录】

【C语言与Python学习笔记目录】 为了极大程度地方便大家查阅资料,我特地将C语言和Python的学习笔记整理成目录的形式,大家直接就可以链接进去,就不用了找了,只需收藏本页就可以。 小白之路艰辛,希望在帮助到大家的同时能收获到大家小小的赞~ C语言 C语言-基础入门-学习笔记(1):概述 C语言-基础入门-学习笔记(2):常量与变量&基本数据类型 C语言-基础入门-学习笔记(3):表达...

qq_42826337的博客 4386

Python之网络编程与粘包现象

socket基于tcp连接示例: server端代码: import socket sk = socket.socket() # 创建一个socket对象 # 又是重启服务端报错“OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次” sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR...

phluo的博客 247
上一篇: python入门开发学习笔记之粘包现象与解决方案
下一篇: python入门开发学习笔记之操作系统介绍
程序员_大白
博客等级 码龄5年 1万+粉丝 4001原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值