Python socket连接中的粘包、精确传输问题实例分析


Posted in Python onMarch 24, 2020

本文实例讲述了Python socket连接中的粘包、精确传输问题。分享给大家供大家参考,具体如下:

粘包:

  • 发生原因:

当调用send的时候,数据并不是即时发给客户端的。而是放到了系统的socket发送缓冲区里,等缓冲区满了、或者数据等待超时了,数据才会发送,所以有时候发送太快的话,前一份数据还没有传给客户端,那么这份数据和上一份数据一起发给客户端的时候就会造成“粘包” 。

  • 解决方案:

解决根源的思想是避免不同段的数据一起发送。

    1. 方案1:前一段数据send完后,等待一段时间再send第二段数据。缺点:时间效率低,而且也无法完全避免问题【因为不清楚该设置多少时间才能保证前一份数据已经发送】
    2. 方案2:握手机制:前一段数据send完后,尝试recv,等待客户端回应,确认第一段数据发送完后,再send第二段数据。完美方案?

方案二的演示:

服务端【发送方】代码:

import socket

server=socket.socket()
server.bind(("localhost",1234))
server.listen()

while True:
  print("正在等待。。。")
  conn,addr=server.accept()
  while True:
    try:
      conn.send(b"first info")
      ack=conn.recv(1024) #接收客户端确认
      print(ack)
      conn.send(b"second info")
    except ConnectionResetError as e:
      print(e)
      break

server.close()

客户端【接收方】代码:

import socket

client=socket.socket()

client.connect(("localhost",1234))

data=client.recv(1024)
print(data.decode())
client.send(b"ack")#发送确认
data=client.recv(1024)
print(data.decode())
client.close()

不精确传输问题:

发生原因:

由于数据太大,发送方一次send不完,而接收方只recv一次,使得影响了后面数据的传输

解决方案:

解决根源的思想是改变recv的次数。

  • 方案:将数据的大小发给接收方,让接收方来决定recv的次数

方案实现代码【以解决长数据shell命令传输为例】:

服务端【发送方】:

import socket,os

server=socket.socket()
server.bind(("localhost",1234))
server.listen()
while True:
  print("正在等待...")
  conn,addr=server.accept()
  print("连接成功!")
  while True:
    try:
      cmd=conn.recv(1024)
      data=os.popen(cmd.decode()).read()
      # print(data)
      cmd_len=len(data.encode())
      print(cmd_len)
      #发现这里如果cmd_len为0会导致异常,有些是没有返回值的command
      if cmd_len==0:
        data="command has nothing return"
        cmd_len=len(data.encode())
      ##因为这里前面没有发送操作,所以不用担心粘包,如果有则要考虑处理
      conn.send(str(cmd_len).encode())#因为len结果是int,所以还要转换
      #这里要处理粘包
      ack=conn.recv(1024)
      conn.send(data.encode())
    except ConnectionResetError as e:
      print(e)
      break

server.close()

客户端【接收方】:

import socket

client=socket.socket()
client.connect(("localhost",1234))
while True:

  cmd = input(">>:")
  client.send(cmd.encode())
  data_len=client.recv(1024)
  data_len=int(data_len.decode())
  print(data_len)
  recv_len=0
  client.send(b'ack')
  total_data=b''
  while recv_len<data_len:
    data=client.recv(1024)
    recv_len+=len(data)
    total_data+=data
  print(total_data.decode())
client.close()
  • 利用这个原理可以实现文件传输,只要能确定接受次数,就能保证文件传输的大小正确。

更多关于Python相关内容可查看本站专题:《Python Socket编程技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python读取mp3中ID3信息的方法
Mar 05 Python
Django中cookie的基本使用方法示例
Feb 03 Python
基于Django URL传参 FORM表单传数据 get post的用法实例
May 28 Python
Tensorflow中使用tfrecord方式读取数据的方法
Jun 19 Python
Python3匿名函数用法示例
Jul 25 Python
详解【python】str与json类型转换
Apr 29 Python
Python实现九宫格式的朋友圈功能内附“马云”朋友圈
May 07 Python
Python PyCharm如何进行断点调试
Jul 05 Python
python代码编写计算器小程序
Mar 30 Python
Python关键字及可变参数*args,**kw原理解析
Apr 04 Python
python开发一款翻译工具
Oct 10 Python
python爬取网页版QQ空间,生成各类图表
Jun 02 Python
Pyqt5 关于流式布局和滚动条的综合使用示例代码
Mar 24 #Python
Python+Appium实现自动化测试的使用步骤
Mar 24 #Python
Python3标准库之dbm UNIX键-值数据库问题
Mar 24 #Python
python网络编程socket实现服务端、客户端操作详解
Mar 24 #Python
python实现批量修改文件名
Mar 23 #Python
Python3 filecmp模块测试比较文件原理解析
Mar 23 #Python
python实现遍历文件夹图片并重命名
Mar 23 #Python
You might like
亲密接触PHP之PHP语法学习笔记1
2006/12/17 PHP
使用 MySQL Date/Time 类型
2008/03/26 PHP
php实现过滤表单提交中html标签的方法
2014/10/17 PHP
php实现粘贴截图并完成上传功能
2015/05/17 PHP
YII视图整合kindeditor扩展的方法
2016/07/13 PHP
Yii框架多语言站点配置方法分析【中文/英文切换站点】
2020/04/07 PHP
Jquery焦点与失去焦点示例应用
2014/06/10 Javascript
JavaScript eval() 函数介绍及应用示例
2014/07/29 Javascript
JS 打印功能代码可实现打印预览、打印设置等
2014/10/31 Javascript
jQuery创建自定义的选择器用以选择高度大于100的超链接实例
2015/03/18 Javascript
javascript实现数组去重的多种方法
2016/03/14 Javascript
jQuery表格插件datatables用法汇总
2016/03/29 Javascript
JavaScript函数柯里化详解
2016/04/29 Javascript
JS上传组件FileUpload自定义模板的使用方法
2016/05/10 Javascript
浅谈js中startsWith 函数不能在任何浏览器兼容的问题
2017/03/01 Javascript
JavaScript中最常见的三个面试题解析
2017/03/04 Javascript
Node.js中.pfx后缀文件的处理方法
2017/03/10 Javascript
Angular 5.0 来了! 有这些大变化
2017/11/15 Javascript
解决Linux无法正常安装与卸载Node.js的方法
2018/01/19 Javascript
Nodejs实现图片上传、压缩预览、定时删除功能
2019/10/25 NodeJs
vue-property-decorator用法详解
2019/12/12 Javascript
Javascript Worker子线程代码实例
2020/02/20 Javascript
微信小程序保存图片到相册权限设置
2020/04/09 Javascript
[01:52]2020年DOTA2 TI10夏季活动预告片
2020/07/15 DOTA
详解Python中最难理解的点-装饰器
2017/04/03 Python
python利用dir函数查看类中所有成员函数示例代码
2017/09/08 Python
python编写猜数字小游戏
2019/10/06 Python
Elasticsearch py客户端库安装及使用方法解析
2020/09/14 Python
python SOCKET编程基础入门
2021/02/27 Python
python包的导入方式总结
2021/03/02 Python
爱奇艺VIP会员:大剧抢先看
2018/07/11 全球购物
喝酒检查书范文
2014/02/23 职场文书
公司人事专员岗位职责
2014/08/11 职场文书
软环境建设心得体会
2014/09/09 职场文书
党支部三严三实对照检查材料思想汇报
2014/09/29 职场文书
党员批评与自我批评发言材料
2014/10/14 职场文书