博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
31 黏包现象
阅读量:4590 次
发布时间:2019-06-09

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

主要内容:

1. 执行命令 :

  在python中去调用操作系统的命令  引入新的模块  : subprocess

import subprocessr = subprocess.Popen('ls',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)# subprocess.Popen(cmd,shell=True,subprocess.stdout,subprocess.stderr)# cmd : 代表系统命令# shell = True   代表这条命令是 系统命令,告诉操作系统,将cmd当成系统命令去执行# stdout   是执行完系统命令之后,用于保存结果的一个管道# stderr   是执行完系统命令之后,用于保存错误结果的一个管道print(r.stdout.read().decode('gbk'))print(r.stderr.read().decode('gbk'))

  用subprocess实现,客户端发送要执行的命令, 服务器执行,执行完结果返回客户端, 客户端拿到结果后呈现在用户眼前.

  服务器端的代码:

import socketimport subprocesssk = socket.socket()sk.bind(('127.0.0.1',8080))sk.listen()conn, addr = sk.accept()ret = conn.recv(1024).decode('utf-8')r = subprocess.Popen(ret, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)stdout = r.stdout.read()stderr = r.stderr.read()if stdout:    conn.send(stdout)else:    conn.send(stderr)conn.close()sk.close()

  客户端的代码:

import socketimport subprocesssk = socket.socket()sk.connect(('127.0.0.1',8080))cmd = input('请用户输入要执行的操作系统的命令:')sk.send(cmd.encode('utf-8'))ret = sk.recv(1024).decode('gbk')    # 操作系统中的编码为gbkprint(ret)sk.close()

2. 黏包问题 :在发送端发送数据,接收端不知道应该如何去接收,造成的一种数据紊乱的现象.

  a :tcp出现黏包的代码:

    服务器端:

import socketsk = socket.socket()sk.bind(('127.0.0.1',8888))sk.listen()conn,addr = sk.accept()conn.send(b'hello')conn.send(b'world')conn.close()sk.close()

  客户端:

import socketsk = socket.socket()sk.connect_ex(('127.0.0.1',8888))msg1 = sk.recv(1024)print('msg1:',msg1)msg2 = sk.recv(1024)print('msg2:',msg2)sk.close()

  b : udp不会出现黏包现象:代码:

    服务器端:

import socketsk = socket.socket(type=socket.SOCK_DGRAM)sk.bind(('127.0.0.1',8888))while 1:    msg1 = sk.recvfrom(5)    print('msg1:',msg1)    msg2 = sk.recvfrom(1024)    print('msg2:',msg2)sk.close()

  客户端:

import socketsk = socket.socket(type=socket.SOCK_DGRAM)while 1:    sk.sendto(b'hello',('127.0.0.1',8888))    sk.sendto(b'world',('127.0.0.1',8888))sk.close()

    c :  tcp协议中,出现两种黏包现象 : 合包机制和拆包机制

  合包机制的过程:

    过程一 : 发送方引起的黏包是由于tcp协议本身引起的, tcp为了提高自己的效率,发送方往往要收集足够多的数据后才发送一个tcp段.

    过程二 : 若连续几次send的数据都比较小,通常tcp会把这些数据打包合成一个tcp后一次性发送过去,这样接收方就收到了黏包数据.

  拆包机制的过程:

    在发送端,因为受到网卡的mtu限制,会将大的超过mtu限制的数据,进行拆分,拆分成多个小的数据,进行传输,当传输到目标主机的操作系统时,会          重新将多个小的数据合成原来的数据.

    当发送端缓冲区的长度大于网卡的MTU时,tcp会将这次发送的数据拆成几个数据包发送出去。

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

3 .  使用udp协议发送数据, 一次收发数据究竟多少合适:

  1): udp不会发生黏包 , udp协议本层对一次收发数据大小的限制是:

    65535 - ip包头(20) - udp包头(8) = 65507

  2): 站在数据链路层, 因为网卡的mtu一般被限制在了1500,所以对于数据链路层来说,收发数据的大小的限制 :

    1500 - ip包头(20) - udp包头(8) = 1472

 

转载于:https://www.cnblogs.com/gyh412724/p/9475532.html

你可能感兴趣的文章
JAVA array,map 转 json 字符串
查看>>
2017-12-27练习
查看>>
NET设计规范(二) 命名规范
查看>>
VMware 9.0.1安装Mac OS X Mountain Lion 10.8.2
查看>>
SSL延迟
查看>>
android新手关于左右滑动的问题,布局把<android.support.v4.view.ViewPager/><ImageView/> 放在上面就不行了。...
查看>>
深入理解DIP、IoC、DI以及IoC容器
查看>>
赋值文件
查看>>
Vue 数组 字典 template v-for 的使用
查看>>
蓝牙模块选择经验谈
查看>>
java中==和equals
查看>>
CCActionPageTurn3D
查看>>
python random
查看>>
esp32-智能语音-cli(调试交互命令)
查看>>
netty与MQ使用心得
查看>>
jquery 实现3d切割轮播图
查看>>
学习spring cloud 笔记
查看>>
字符串截取,SubString
查看>>
Android: 网络随时需要在3G和Wifi切换,网络程序需要注意
查看>>
ajax调用servlet
查看>>