网络编程基础粘包现象

粘包

  • 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()

原文地址:https://www.cnblogs.com/yuncong/p/9665453.html

时间: 2024-11-08 06:33:27

网络编程基础粘包现象的相关文章

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

一.什么是粘包 须知:只有TCP有粘包现象,UDP永远不会粘包 粘包不一定会发生 如果发生了:1.可能是在客户端已经粘了 2.客户端没有粘,可能是在服务端粘了 首先需要掌握一个socket收发消息的原理 应用程序所看到的数据是一个整体,或说是一个流(stream),一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因.(因为TCP是流式协议,不知道啥时候开始,啥时候结束).而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提

Learning-Python【29】:网络编程之粘包

粘包问题 上一篇博客遗留了一个问题,在接收的最大字节数设置为 1024 时,当接收的结果大于1024,再执行下一条命令时还是会返回上一条命令未执行完成的结果.这就是粘包问题. 因为TCP协议又叫流式协议,每次发送给客户端的数据实际上是发送到客户端所在操作系统的缓存上,客户端就是一个应用程序,需要通过操作系统才能调到缓存内的数据,而缓存的空间是一个队列,有 “先进先出” 的思想,当第一次的 tasklist 数据未接收完,第二次又来一个 dir 的数据时,只能等第一次先全部接收完成才会接收后面的.

网络编程 之粘包问题、使用socketserver实现并发

一.粘包问题 注意:粘包问题只有tcp协议并且udp协议永远不会粘包 粘包问题的产生: 简述:粘包问题的产生主要是由于tcp协议传输数据(其内置的nagle算法来进行的)会将数据较小的且发送时间较短的合并成一个包从发送端发送出去,接收端不知道该怎么去想要的数据拿出来这样造成了粘包问题,另一方面是由于时间太短接收端没有及时拿干净 传来的数据造成数据混乱(这是因为tcp协议又叫流氏协议指的是其就像水流一样传输数据)才产生的粘包问题. 1.发送端由于时间太短造成多个包合在一起发送产生粘包问题的实例如下

网络编程中粘包的处理方法

写在前面的话:因为自己是才解除网络编程,在工作中第一次遇到粘包问题,我还不知道它是叫粘包问题,所以被整的晕头转向,百思不得其解,自己的代码到底哪里出了问题,最后只能单步调试程序才发现接收方接收到的数据并不一定是按自己设想那样,一次接收整个数据包,当时就想到用文件长度来判断是否接收完文件,之后读了UNP才知道是粘包问题.记录以下当时自己的处理方法. 面对网络编程中的发送文件时的粘包问题,我的处理方法是在要发送文件前,首先发送文件的长度,获取的文件长度是UlongLong类型的整数,发送 时需要转换

网络编程ssh,粘包

1.什么是socket? TCP,可靠地,面向连接协议,有阻塞rect udp,不可靠的,无线连接的服务 这里因为不需要阻塞,所以速度会很快,但安全性不高 2.关于客户端退出而服务器未退出的解决办法 1 import socket 2 sock=socket.socket() # TCP协议 3 IP_PORT=("127.0.0.1",8899) 4 sock.bind(IP_PORT) 5 sock.listen(5) 6 while 1: 7 conn,addr=sock.acc

网络编程之粘包

粘包: 传输层协议有tcp和udp两种 tcp:Transmission Control Protocol 传输控制协议,基于数据流,收发的消息不能为空,需要在客户端和服务端都添加空消息的处理机制 tcp是可靠性协议,数据的收发都需要确认信息,这就降低了传输效率,故为了减少确认次数,tcp采用了nagle算法 将多次间隔短且数据小的数据合成一个数据流,然后发送,tcp的数据没有明确的界限,无法区分数据的开始和结束, 这就导致了可能将多个信息并为一条信息,也就是粘包 还有一种粘包情况是当一个数据包

网络编程- 解决黏包现象方案一(六)

队列 利用队列的思路来解决黏包问题 总结 原文地址:https://www.cnblogs.com/mys6/p/10797907.html

网络编程- 解决黏包现象方案二之struct模块(七)

server端 import jsonimport structimport socket sk = socket.socket()sk.bind(('127.0.0.1',8080))sk.listen() conn,addr = sk.accept()dic_len = conn.recv(4) # 4个字节 数字的大小dic_len = struct.unpack('i',dic_len)[0]content = conn.recv(dic_len).decode('utf-8') # 7

解决网络编程的粘包问题

# 服务端 import socketimport subprocessimport structimport json servers = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)servers.bind(('127.0.0.1', 7777))servers.listen(10)print('start settings') while True:    """连接循环""