网络编程基础粘包现象(代码片段)

yuncong yuncong     2023-01-01     292

关键词:

粘包

  • tcp是流式传输,字节流,数据与数据之间是没有边界的
    • 流式传输优点:
      • 不限定长度
      • 可靠传输
    • 缺点:
      • 和一个人的通信连接conn会一直占用我们的通信资源
  • udp协议,面向数据包的传输
    • 数据包优点
      • 由于不需要建立连接,所以谁发的消息我都能接受到
    • 缺点
      • 不能传输过长的数据
      • 不可靠

粘包现象

  • 由于流式传输的特点,产生了数据连续发送的粘包现象。
    • 在一个conn建立起来的连接上传输的多条数据是没有边界的
  • 数据的发送和接收实际上不是在执行send/recv的时候就立刻被发送和接收,而是需要经过操作系统内核
  • Nagle 算法,能够将发送间隔实际很近的短数据合成一个包发送到接收端
  • 拆包机制: 当要发送的数据超过了网络上能够传输的最大长度,就会被tcp协议强制拆包

解决粘包问题

  • struct模块

    • park("i",len(msg)) 把数字转成4字节

    • unpack("i",bytes)[0] 把四字节转换成长度

    • server端
      import struct
      import socket
      
      sk = socket.socket()
      sk.bind((‘127.0.0.1‘,9090))
      sk.listen()
      
      conn,addr = sk.accept()
      while True:
          s = input(‘>>>‘).encode(‘utf-8‘)
          pack_num = struct.pack(‘i‘,len(s))
          conn.send(pack_num)
          conn.send(s)
      conn.close()
      sk.close()
    • client端
      import socket
      import struct
      sk = socket.socket()
      sk.connect((‘127.0.0.1‘,9090))
      
      while True:
          pack_num = sk.recv(4)
          num = struct.unpack(‘i‘,pack_num)[0]
          ret = sk.recv(num)
          print(ret.decode(‘utf-8‘))
      sk.close()

并发的 socketserver

  • 实现同一时刻server端可以和多个client端建立连接

验证客户端链接的合法性

  • server端

  • import os
    import hmac
    import socket
    def auth(conn):
        msg = os.urandom(32)  # # 生成一个随机的字符串
        conn.send(msg)  # # 发送到client端
        result = hmac.new(secret_key, msg)  # 处理这个随机字符串,得到一个结果
        client_digest = conn.recv(1024)  # 接收client端处理的结果
        if result.hexdigest() == client_digest.decode(‘utf-8‘):
            print(‘是合法的连接‘)  # 对比成功可以继续通信
            return True
        else:
            print(‘不合法的连接‘)  # 不成功 close
            return False
    secret_key = b‘alex_sb‘
    sk = socket.socket()
    sk.bind((‘127.0.0.1‘,9000))
    sk.listen()
    conn,addr = sk.accept()
    if auth(conn):
        print(conn.recv(1024))
        # 正常的和client端进行沟通了
        conn.close()
    else:
        conn.close()
    sk.close()
  • client端

  • import hmac
    import socket
    def auth(sk):
        msg = sk.recv(32)
        result = hmac.new(key, msg)
        res = result.hexdigest()
        sk.send(res.encode(‘utf-8‘))
    
    key = b‘alex_s‘
    sk = socket.socket()
    sk.connect((‘127.0.0.1‘,9000))
    auth(sk)
    sk.send(b‘upload‘)
    # 进行其他正常的和server端的沟通
    sk.close()

day32udp协议socketserver模块,并发编程基础(代码片段)

一.粘包现象  1.为什么会出现粘包现象    1.只有在TCP协议中才会出现粘包现象,因为TCP协议是流式协议    2.TCP协议的特点是将数据量小、时间间隔比较短的数据一次性打包发送    3.粘包现象的本质是因为不知... 查看详情

粘包现象(代码片段)

udp协议是不存在粘包现象的,因为它文件的传输方式就是面向包的tcp协议是有可能出现粘包现象的,它存在粘包的情况有两种:a.连续发送小包,如果出现网络延迟现象的话,两次发送的消息会一次性被接收b.如果一次性发送的,文件过... 查看详情

网络编程之粘包(代码片段)

一、什么是粘包须知:只有TCP有粘包现象,UDP永远不会粘包粘包不一定会发生TCP发生粘包的两种情况:      1.由于Nagle算法,将多次间隔小且数量小的数据,合并成一个数据块      2.数据量发送大,接受少首先需... 查看详情

netty进阶——粘包与半包(代码示例)(代码片段)

目录一、消息粘包和消息半包的概述1.1、消息粘包1.2、消息半包二、粘包现象代码示例2.1、粘包现象服务端示例代码2.2、粘包现象客户端示例代码2.3、分别启动服务端,客户端,查看服务端结果输出三、半包现象代码示... 查看详情

网络编程粘包问题(代码片段)

    首先说为什么会粘包,在py2上运行时,服务器把两次发送的操作强制的合成一次发送给客户端,所以粘在一起了,因为python3的版本是可以的,但是有的时候python3也会出现粘包现象。  解决粘包的问题有两种方法: ... 查看详情

粘包现象(代码片段)

一、subprocessimportsubprocesscmd=input("请输入指令>>>")res=subprocess.Popen(cmd,#字符串指令:"dir","ipconfig"等shell=True,#使用shell,就相当于使用cmd窗口stderr=subprocess.PIPE,#标准错误输出,凡是输入错误指令,错误指令输出的报错信息就会被... 查看详情

基于tcp协议下粘包现象和解决方案(代码片段)

一、缓冲区  每个socket被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区。write()/send()并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器。一旦将数据写入到缓冲区... 查看详情

解决粘包现象(代码片段)

简单版服务端 #!/usr/bin/envpython#_*_coding:utf-8_*_#Author:Mr.yangimportsocketimportstructimportsubprocessphone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)phone.bind((‘127.0.0.1‘,8080))phone.list 查看详情

粘包现象(代码片段)

套接字的类型      基于文件类型的套接字家族:AF_UNIX             基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可... 查看详情

网络编程(代码片段)

阅读目录一客户端/服务器架构二osi七层三socket层四socket是什么五套接字发展史及分类六套接字工作流程七基于TCP的套接字八基于UDP的套接字九粘包现象十什么是粘包十一解决粘包的low比处理方法十二峰哥解决粘包的方法十三认... 查看详情

网络编程-之------粘包现象

一、什么是粘包须知:只有TCP有粘包现象,UDP永远不会粘包粘包不一定会发生如果发生了:1.可能是在客户端已经粘了      2.客户端没有粘,可能是在服务端粘了首先需要掌握一个socket收发消息的原理应用程序所看到的... 查看详情

day26粘包(代码片段)

一、粘包现象只有TCP有粘包现象,UDP永远不会粘包res=subprocess.Popen(cmd.decode(‘utf-8‘),shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)的结果的编码是以当前所在的系统为准的,如果是windows,那么res.stdout.read()读出的就是GBK编码的,在... 查看详情

粘包和拆包(代码片段)

写在前面粘包、拆包是Socket编程中最常遇见的一个问题,本文只对粘包、拆包现象及发生的原因做简要分析,具体如何解决粘包和拆包的问题,在后续文章中会详细介绍。什么是粘包、拆包TCP是个"流"协议,所谓流,就是没有界... 查看详情

透过现象看本质,我找到了netty粘包与半包的这几种解决方案。(代码片段)

1、粘包与半包啥也不说了,直接上代码是不是有点不太友好,我所谓了,都快过年了,还要啥自行车我上来就是一段代码猛如虎1.1服务器代码publicclassStudyServerstaticfinalLoggerlog=LoggerFactory.getLogger(StudyServer.class);voidstart()NioEventLoopGrou... 查看详情

20网络编程粘包现象与解决方案

1、https://www.cnblogs.com/guobaoyuan/p/6809447.html 发送数据包前对包的长度进行计算1.比较low的方法是len(package)然后直接发送给接收端。这样会出现一个问题,就是接收端不知道你的这个len(package)是几个字节,就也有可能会出现粘包... 查看详情

网络编程之基于udp协议套接字(代码片段)

1.UDP协议介绍(数据报协议)  UDP协议不同于TCP,通信时,它不需要事先建立双向链接,并且不区分客户端先启动还是服务端前起,工作原理:基于udp协议传输的信息,协议会将数据自动加上自定义的报头,这样每一个数据都是... 查看详情

socket套接字(代码片段)

...字符串的形式send给客户端windows操作系统的默认编码是gbk粘包粘包的两种方式连续短暂的多次send,数据量很小,数据就会统一发出去send的数据过大,大于对方recv的上限时,对方第一次recv时,会接收上一次没有recv完的剩余数据... 查看详情

第六章-网络编程-粘包(代码片段)

1.粘包:多个包多个命令的结果粘到一起了因为recv1024限制了导致的结果参考:http://www.cnblogs.com/linhaifeng/articles/6129246.html粘包底层原理分析:1.运行一个软件和哪几个硬件有关硬盘内存cpu2.启动程序:硬盘程序加载到内存启一个软... 查看详情