粘包

2018-08-17 09:48:43来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

  一, subprocess模块

  可以执行操作系统的命令,即可以返回正确结果,也可以返回错误结果

  1. 语法:

import subprocess
r=subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
#subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)    
#cmd : 代表系统命令
#shell=True 代表这条命令是系统命令,告诉操作系统将cmd当成系统命令执行
#stdout : 是执行完系统命令后,用于保存结果的一个管道(管道的内容只能取一次)
#stderr : 是执行完系统命令之后,用于保存错误结果的一个管道(只能取一次) 

print(r.stdout.read().decode('gbk'))

print(r.stderr.read().decode('gbk'))

 

  2. 用途举例:

   需求: 客户端发送要执行命令 ; 服务器执行,执行完将结果返回给客户端 ; 客户端拿到结果呈现到

    用户眼前

客户端

import socket
sk = socket.socket()
sk.connect(('127.0.0.1',7080))

com = input('请输入命令:>>')
sk.send(com.encode('utf-8'))    #发送给服务器要执行的命令
resuld = sk.recv(10240).decode('gbk')#win默认gbk编码  此处接收服务器端发送的命令执行结果
print(resuld)

sk.close()


服务器端

import socket
import subprocess
sk = socket.socket()
sk.bind(('127.0.0.1',7080))
sk.listen()

conn , addr = sk.accept()
cmd = conn.recv(10240).decode('utf-8')    #接收到客户端要执行的命令
r = subprocess.Popen(cmd,shell = True,stdout=subprocess.PIPE,
                                  stderr = subprocess.PIPE  )  #调用操作系统执行命令

stdout = r.stdout.read()
stderr = r.stderr.read()
if stderr :    #若果命令执行后错误管道不为空,则执行
    conn.send(stderr)
else:    #若错误管道为空,则执行
    conn.send(stdout)

conn.close()
sk.close()

 

二, 粘包

  只有tcp协议有,udp协议不会发生粘包.

  nagle算法(合包机制) : 把缓存区连续间隔时间较短的数据块打包统一发送,

 

服务器端

# import socket
# sk = 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 socket
# sk = 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()

#粘包时结果为 : msg1:b'helloworld'
         msg2:b''

 

  合包机制:

 

  拆包机制

  在发送端,因为受到网卡的MTU限制,会将大的超过MTU限制的数据,进行拆分,拆分成多个小的

  数据,进行传输,当传输到目标主机的操作系统层时,会重新将多个小的数据合并成原本的数据

 

  udp协议不会发生粘包

  udp协议本层对一次收发数据大小的限制是:

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

   站在数据链路层,因为网卡的MTU一般被限制在了1500,所以对于数据链路层来说,一次收发数

  据的大小被限制在  1500 - ip包头(20) - udp包头(8) = 1472

  得到结论:

      如果sendto(num)

       num > 65507  报错

       1472 < num < 65507  会在数据链路层拆包,而udp本身就是不可靠协议,所以一旦拆包之

    后,造成的多个小数据包在网络传输中,如果丢任何一个,那么此次数据传输失败

       num < 1472 是比较理想的状态

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:python_爬虫_通过selenium获取人人网cookie值并模拟登陆个人界面

下一篇:Python之路,Day1 - Python基础1