zoukankan      html  css  js  c++  java
  • 网络编程之黏包

    先来了解一下缓冲区:

    每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区。
    
    write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器。一旦将数据写入到缓冲区,函数就可以成功返回,不管它们有没有到达目标机器,也不管它们何时被发送到网络,这些都是TCP协议负责的事情。
    
    TCP协议独立于 write()/send() 函数,数据有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这取决于当时的网络情况、当前线程是否空闲等诸多因素,不由程序员控制。
    
    read()/recv() 函数也是如此,也从输入缓冲区中读取数据,而不是直接从网络中读取。
    这些I/O缓冲区特性可整理如下:
    
    1.I/O缓冲区在每个TCP套接字中单独存在;
    2.I/O缓冲区在创建套接字时自动生成;
    3.即使关闭套接字也会继续传送输出缓冲区中遗留的数据;
    4.关闭套接字将丢失输入缓冲区中的数据。
    
    输入输出缓冲区的默认大小一般都是 8K,可以通过 getsockopt() 函数获取:
    
    1.unsigned optVal;
    2.int optLen = sizeof(int);
    3.getsockopt(servSock, SOL_SOCKET, SO_SNDBUF,(char*)&optVal, &optLen);
    4.printf("Buffer length: %d
    ", optVal);

    关于黏包:

    MTU是Maximum Transmission Unit的缩写。意思是网络上传送的最大数据包。MTU的单位是字节。 大部分网络设备的MTU都是1500个字节,也就是1500B。如果本机一次需要发送的数据比网关的MTU大,大的数据包就会被拆开来传送,这样会产生很多数据包碎片,增加丢包率,降低网络速度

    模拟一个黏包现象:

    先学一个subprocess模块。

    import subprocess
    cmd = input('请输入指令>>>')
    res = subprocess.Popen(
        cmd,                     #字符串指令:'dir','ipconfig',等等
        shell=True,              #使用shell,就相当于使用cmd窗口
        stderr=subprocess.PIPE,  #标准错误输出,凡是输入错误指令,错误指令输出的报错信息就会被它拿到
        stdout=subprocess.PIPE,  #标准输出,正确指令的输出结果被它拿到
    )
    print(res.stdout.read().decode('gbk'))
    print(res.stderr.read().decode('gbk'))
    黏包
  • 相关阅读:
    .Net操作Sharepoint常用方法(1) 判断List或Library是否存在
    Aspose.Cells读取Excel获取DataTable方法
    Nginx系统学习笔记(1)Say Hello
    老刘Hadoop学习笔记(6)Hadoop 单机模式 伪分布式 完全分布式区别
    老刘Hadoop学习笔记(5)安装JDK
    老刘Hadoop学习笔记(4)JDK和Open JDK区别
    老刘Hadoop学习笔记(3)新建用户及用户组
    老刘Hadoop学习笔记(2)修改虚拟机hostname及hosts文件
    老刘Hadoop学习笔记(1)开始学习
    MySQL中变量为空时不执行where过滤
  • 原文地址:https://www.cnblogs.com/wangzhilong/p/10239553.html
Copyright © 2011-2022 走看看