zoukankan      html  css  js  c++  java
  • 基于TCP和UDP的套接字方法 粘包问题 丢包问题

    TCP 基于流的协议

    又叫可靠性传输协议 通过三次握手 四次挥手 来保证数据传输完毕 缺点效率低

    正因为是基于流的协议 所以会出现粘包问题
    粘包问题:原因一:是应为数据是先发送给操作系统,在操作系统中有一个缓冲池 ,操作系统并不会马上把数据发送给服务器端的缓冲池,而是在自己的缓冲池中,

    操作系统会将数据小,发送间隔短的数据进行底层优化,然后一起发送出去就造成了数据的混合,以至于到了服务器哪里的缓冲池也区分不出来,造成的粘包

    原因二,数据发到服务器的缓冲池中,服务器没有及时发送给应用软件接收,造成了在服务器缓冲池中的粘包

    根本原因:是因为接收方在接收数据的时候不知道数据的长度是多少,故在服务器的操作系统缓冲池中取不到正确长度的数据,造成了数据取多,或者取少,导致的粘包问题
    解决的方法 导入struct模块

    客户端:

    import socket
    import struct
    """
    解决粘包的核心思路就是
    先通知接收方 要发送的数据的长度
    在发送真实数据
    问题在于 数据长度 也是不确定的
    对方也不清楚 长度信息 到底是几个字节
    要想办法 将长度信息所占的字节数 固定下来
    """
    c = socket.socket()
    c.connect(("127.0.0.1",8888))
    # 要发送的数据
    data = "{'name':'jerry'}".encode("utf-8")
    # 给接收方发送数据的长度
    length = len(data)
    # 将整型的长度 转为固定长度的字节
    len_data = struct.pack("q",length)
    # 发送长度信息
    c.send(len_data)
    # 发送真实数据
    c.send(data)

    服务器:

    import socket
    import struct
    """
    TCP 的粘包问题
    TCP 流式协议
    基于数据流的协议

    """
    s = socket.socket()
    s.bind(("127.0.0.1",8888))
    s.listen()
    c,addr = s.accept()

    # 先接收长度
    # 有可能 长度信息和真实数据也黏在一起 无法取出长度信息

    # 解决方案是 把长度信息 转换为一个固定字节数的二进制数据
    # 1 4个字节的bytes
    # 2 4个字节的bytes
    # 20000 4个字节的bytes
    # 接收数据的长度信息
    length = struct.unpack("q",c.recv(8))[0]
    print("长度为:%s" % length)
    data = c.recv(length).decode("utf-8")
    print(data)

    UDP 基于数据报的传输协议

    传输效率高,但不关心对方是否收到数据  可以放在语音通话 和视频通话上

    udp是放在数据帧里面传输的 数据帧最多放1500个字节,除去udp的报头 一个数据帧最多发送1472个字节的udp,如果udp过大

    就会被拆分成多个数据帧发送到网络,即会造成丢包的现象

  • 相关阅读:
    MyEclipse2014安装插件的几种方式(适用于Eclipse或MyEclipse其他版本)
    淘淘商城 本地仓库配置和仓库jar包下载
    淘淘商城的第一天
    Oracle12c 性能优化攻略:攻略1-1:创建具有最优性能的数据库
    Eclipse开发环境配置
    Oracle12c 性能优化攻略:攻略目录表
    将日期或数据转换为char数据类型 TO_CHAR(x[[,c2],C3])
    根据条件返回相应值 decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)
    【功能】返回数据类型、字节长度和在内部的存储位置.DUMP(w[,x[,y[,z]]])
    alter table的用法
  • 原文地址:https://www.cnblogs.com/tangda/p/10474035.html
Copyright © 2011-2022 走看看