博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网络编程基础粘包现象
阅读量:5340 次
发布时间:2019-06-15

本文共 1915 字,大约阅读时间需要 6 分钟。

粘包

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

粘包现象

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

解决粘包问题

  • struct模块

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

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

    • server端import structimport socketsk = 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 socketimport structsk = 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 osimport hmacimport socketdef 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 Falsesecret_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 hmacimport socketdef 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()

转载于:https://www.cnblogs.com/yuncong/p/9665453.html

你可能感兴趣的文章
Bit Twiddling Hacks
查看>>
Windwos中的线程同步
查看>>
LeetCode : Reverse Vowels of a String
查看>>
时间戳与日期的相互转换
查看>>
jmeter(五)创建web测试计划
查看>>
python基本数据类型
查看>>
1305: [CQOI2009]dance跳舞 - BZOJ
查看>>
关于TDD的思考
查看>>
Cocos2d-x学习之windows 7 android环境搭建
查看>>
将html代码中的大写标签转换成小写标签
查看>>
jmeter多线程组间的参数传递
查看>>
零散笔记
查看>>
学 Win32 汇编[22] - 逻辑运算指令: AND、OR、XOR、NOT、TEST
查看>>
MaiN
查看>>
[Python学习] 简单网络爬虫抓取博客文章及思想介绍
查看>>
触发器课程SQL Server 知识梳理九 触发器的使用
查看>>
信息浏览器从Android的浏览器中传递cookie数据到App中信息浏览器
查看>>
客户端连接linux虚拟机集群报错
查看>>
linux下部署一个JavaEE项目的简单步骤
查看>>
hash储存机制
查看>>