网络编程之黏包

先来了解一下缓冲区:程序员

每一个 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\n", optVal);

关于黏包:shell

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

模拟一个黏包现象:网络

先学一个subprocess模块。socket

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'))
黏包
相关文章
相关标签/搜索