博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python--day32--复习:https和http的区别;黏包;黏包问题的解决方式;
阅读量:7101 次
发布时间:2019-06-28

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

1,https和http的区别:

  https比较安全,传输的时候先对内容进行加密,收到后再进行解密;它的传输内容不容易拦截,就算拦截下来了,也是加密的,看不懂。但是要买证书,一年要好几万,小公司承担不起。听说非常安全,在业内都没有出过问题。

2,udp不会黏包,只有tcp会黏包

  传输的时候只能传输bite类型数据

  demo1--远程执行命令:

server.py

sk = socket.socket()sk.bind(('127.0.0.1', 8080))sk.listen()conn,addr = sk.accept()while True:    cmd = input('>>>')    if cmd == 'q':        conn.send(b'q')        break    conn.send(cmd.encode('gbk'))    res = conn.recv(1024).decode('gbk')    print(res)conn.close()sk.close()

client.py

#接收server端的命令之后在自己的机器上执行import socket#找个什么人去帮你执行程序import subprocess#创建一个sokect的对象sk = socket.socket()sk.connect(('127.0.0.1', 8080))while True:    #收1024个字节    cmd = sk.recv(1024).decode('gbk')    if cmd == 'q':        break    #把接收的结果预先存到PIPE管道里面,就是装数据的容器    res = subprocess.Popen(cmd,shell=True,                     stdout=subprocess.PIPE,                     stderr=subprocess.PIPE)    sk.send(res.stdout.read())    sk.send(res.stderr.read())sk.close()

黏包现象:

 

3、什么是黏包问题,这里终于讲清楚了:

黏包(是tcp协议内部的优化算法造成的):

  client接收数据的时候,分两次接收,第一次接收的时候假如只接收两个的话,第二次接收的时候就不会接收得到十个数据,只能接收掉了八个数据。

  如果是udp,第一次接收了两个数据,第二次接收是接收不到数据的,因为后面八位数据已经丢失了。

  只有tcp中有缓存机制才能发生第二次接收的时候从缓存中接收到剩下的机制,这种现象就是黏包现象。第一次没有完全接收,第二次就会把剩下的发给我,这种问题就是黏包问题

  现在用到的所有的网络传输都是基于socket的

 

   #优化算法

  #连续的小数据包会被合并

  #多个send 小的数据连在一起,会发生黏包现象,是tcp协议内部的优化算法造成的

  #连续使用了send

  client端发送信息的机制:

    当把所需要的消息发送完关闭之后,默认再往服务器发送一个空消息。(比较高点版本的Windows系统会发送空消息,比较低版本的Windows系统直接报错,我在win7下测试发送的也是空消息)

  client2.py

  server2.py

  #在tcp优化算法中,只有在非常短的时间内接收到消息,才会发生黏包,

  #如果等了一段时间,比如一个网络延时了,就会先发先走

  server2.py

  client2.py

4、发生黏包的原因:

  1,连续send两个小数据

  2,两个recv,第一个recv特别小

  #发生黏包的本质就是你不知道到底要接收多大的数据

 

5、黏包问题的解决方式

  1,方法1:

    首先:发送一下这个数据到底有多大

    再按照数据的长度接收数据

  #好处:确定了我到底要接收多大的数据       #要在文件中配置一个配置项:就是每一次recv的大小  buffer = 4096       #当我们要发送大数据的时候,要明确的告诉接收方要发送多大的数据,以便接收方能够准确的接收到所有的数据       #多用在文件传输的过程中           #大文件的传输 一定是按照字节读 每一次读固定的字节           #传输的过程中 一边读一边传 接收端 一边收一边写           #send这个大文件之前,35672字节 send(4096) 35672-4096-4096 -->0           #recv这个文件,recv 35672字节 recv(2048) 35672-2048 -->0   #不好的地方:多了一次交互   #send sendto 在超过一定的范围的时候 都会报错   #程序的内存管理   程序:   client.py
1 #接收server端的命令之后在自己的机器上执行 2 import socket 3 #找个什么人去帮你执行程序 4 import subprocess 5  6 #创建一个sokect的对象 7 sk = socket.socket() 8 sk.connect(('127.0.0.1', 8080)) 9 while True:10     #收1024个字节11     cmd = sk.recv(1024).decode('gbk')12     if cmd == 'q':13         break14     #把接收的结果预先存到PIPE管道里面,就是装数据的容器15     res = subprocess.Popen(cmd,shell=True,16                      stdout=subprocess.PIPE,17                      stderr=subprocess.PIPE)18     std_out = res.stdout.read()19     std_err = res.stderr.read()20     sk.send(str(len(std_out)+len(std_err)).encode('utf-8'))#200021     #这里一般不超过4096个,过大会给运行内存造成巨大的压力22     sk.recv(4096)   #ok23     sk.send(std_out)24     sk.send(std_err)25 sk.close()

  server.py

1 #server 下发命令 给client 2  3 import socket 4 sk = socket.socket() 5 sk.bind(('127.0.0.1', 8080)) 6 sk.listen() 7 conn,addr = sk.accept() 8 while True: 9     cmd = input('>>>')10     if cmd == 'q':11         conn.send(b'q')12         break13     conn.send(cmd.encode('gbk'))14     num = conn.recv(1024).decode('utf-8')15     conn.send(b'ok')16     res = conn.recv(int(num)).decode('gbk')17     print(res)18 conn.close()19 sk.close()

   2,方法2:struct模块解决黏包问题(看红色的代码)

      init.py

1 import struct 2  3 ret = struct.pack('i', 4096) #‘i’代表int,就是即将要把一个数字转换成固定长度bytes类型 4 print(ret) 5  6 num = struct.unpack('i', ret) 7 print(num[0]) 8  9 #如果发送数据的时候10 #先发送长度  先接收长度

      server.py

1 import struct 2 import socket 3 sk = socket.socket() 4 sk.bind(('127.0.0.1', 8080)) 5 sk.listen() 6 conn,addr = sk.accept() 7 while True: 8     cmd = input('>>>') 9     if cmd == 'q':10         conn.send(b'q')11         break12     conn.send(cmd.encode('gbk'))13     num = conn.recv(4)  #204814     num = struct.unpack('i', num)[0]    #204815     res = conn.recv(int(num)).decode('gbk')16     print(res)17 conn.close()18 sk.close()

    client.py

1 import struct 2 import socket 3 #找个什么人去帮你执行程序 4 import subprocess 5  6 #创建一个sokect的对象 7 sk = socket.socket() 8 sk.connect(('127.0.0.1', 8080)) 9 while True:10     #收1024个字节11     cmd = sk.recv(1024).decode('gbk')12     if cmd == 'q':13         break14     #把接收的结果预先存到PIPE管道里面,就是装数据的容器15     res = subprocess.Popen(cmd,shell=True,16                      stdout=subprocess.PIPE,17                      stderr=subprocess.PIPE)18     std_out = res.stdout.read()19     std_err = res.stderr.read()20     len_num = len(std_out)+len(std_err)21 22     num_by = struct.pack('i', len_num)23     sk.send(num_by) #4  204824     sk.send(std_out)#102425     sk.send(std_err)#1024   4+204826 sk.close()

 

 

 

转载于:https://www.cnblogs.com/xudj/p/10295063.html

你可能感兴趣的文章
2018.4.18 五周第一次课
查看>>
SQL语句的添加、删除、修改多种方法
查看>>
快速排序算法真的正确吗?-试试120,100,105,103,118 从大到小排列
查看>>
Linux基础操作
查看>>
使用标准输入框 --- Qt
查看>>
PDF怎么翻译
查看>>
怎样加密数据以及怎样恢复加密数据
查看>>
fdisk和 parted 磁盘分区 以及 vimrc
查看>>
Collection
查看>>
抖音云控专业营销实战引流,一键暴涨百万精准粉原理!
查看>>
golang学习的点点滴滴:channel缓冲区
查看>>
springboot 之缓存注解
查看>>
apt-get install 的用法
查看>>
如何写高效率的SQL
查看>>
利用灰名单阻止垃圾邮件
查看>>
Cisco 路由器加电/启动顺序
查看>>
HTTP X-Forwarded-For 头部字段的应用
查看>>
【翻译】安卓 opengl ES教程之六——纹理
查看>>
我的友情链接
查看>>
ncat使用总结
查看>>