python粘包问题及socket套接字编程详解


Posted in Python onJune 29, 2019

粘包问题

TCP协议在传输过程中会出现数据粘包问题

讲一下TCP和UDP的区别,都是传数据的协议,没有好坏之说,只是不同的应用需求可能会更好选择哪一个协议

TCP:适合传输数量大 ,需要建立连接,会出现粘包问题,粘包问题可以解决,确定传入的长度,接收同样长度就可以保证一次性传输完

UDP: 适合传输数据量小,没有粘包,不需要连接,一次性传输,下一次就是新的数据,弊端就是数据丢失,不安全

QQ是用什么协议呢?按理应该可以用UDP协议,但是实际用的是TCP协议,这是历史遗留问题,可还记得我们输入QQ一次性输入的内容字数有限制吗?就是规定了发送与接收的数据长度是一样的.

形成粘包的原因

1.两个数据非常小,然后间隔时间又短

2.数据太大,一次取不完,下一次还会取这个大数据

解决粘包问题

==在传数据之前,传一个数据的大小,数据的大小必须得定长==

# TCP 解决粘包问题 附带处理了一下
import socket
import struct
import subprocess
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 8000))
server.listen(5)
print('start...')
# 连接循环
while True:
conn, client_address = server.accept()
print(client_address)
# 通信循环
while True:
try:
cmd = conn.recv(1024)
print(cmd)
pipeline = subprocess.Popen(cmd.decode('utf8'),
shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
stdout = pipeline.stdout.read()
stderr = pipeline.stderr.read()
count_len = len(stdout) + len(stderr)
guding_bytes = struct.pack('i', count_len)
conn.send(guding_bytes) # 4
conn.send(stderr + stdout)
except ConnectionResetError: # 连接循环时出现的中断
break
conn.close()
# 客户端
mport struct
from socket import *
client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8000))
while True:
# cmd = input('please enter your cmd you want:')
cmd = 'dir'
client.send(cmd.encode('utf8'))
guding_bytes = client.recv(4)
count_len = struct.unpack('i', guding_bytes)[0]
data = client.recv(count_len)
print(data.decode('gbk'))

基于UDP协议的socket套接字编程

UDP 无连接

# UDP服务端
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(('127.0.0.1', 8000))
print('start...')
while True:
data, client_addr = server.recvfrom(1024)
print(client_addr)
print(data)
server.sendto(data.upper(), client_addr)
# UDP客户端
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
msg = input('please enter your msg:')
client.sendto(msg.encode('utf8'), ('127.0.0.1', 8000))
data = client.recvfrom(1024)
print(data)

和TCP是差不多的,调用的功能是一样的,只是方法名的具体表示方法不一样,因为UDP无连接,UDP的sendto和TCP的send ,就是UDP的sendto要直接指到地址的

基于socketserver实现并发的socket套接字编程

让服务端同时和多个客户端进行连接,以前我们写的是一个警局有五部电话只有一个人,现在写的五部电话五个人

# 同一时刻有多个人在接听
import socketserver
import subprocess 
import struct
class MyHandler(socketserver.BaseRequestHandler):
# 通信循环
def handle(self):
while True:
try:
cmd = self.request.recv(1024)
print(cmd)
pipeline = subprocess.Popen(cmd.decode('utf8'),
shell = True,
stderr = subprocess.PIPE,
stdout = subprocess.PIPE)
stdout = pipeline.stdout.read()
stderr = pipeline.stderr.read()
count_len = len(stderr) + len(stdout)
guding_bytes = struct.pack('i', count_len)
self.request.send(guding_bytes) # 4
self.request.send(stderr + stdout)
except ConnectionResetError:
break
# 使用socketserver的连接循环(并发),但是使用了自己的通信循环
# myhandler = MyHandler()
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1', 8000), MyHandler, bind_and_activate=True)
print('start...')
server.serve_forever()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python 学习笔记
Dec 27 Python
python文件和目录操作函数小结
Jul 11 Python
在Python中处理字符串之isdigit()方法的使用
May 18 Python
如何在Python函数执行前后增加额外的行为
Oct 20 Python
win与linux系统中python requests 安装
Dec 04 Python
详解Python 模拟实现生产者消费者模式的实例
Aug 10 Python
Python实现比较扑克牌大小程序代码示例
Dec 06 Python
django的聚合函数和aggregate、annotate方法使用详解
Jul 23 Python
解决Atom安装Hydrogen无法运行python3的问题
Aug 28 Python
Django框架模板用法入门教程
Nov 04 Python
使用Python完成15位18位身份证的互转功能
Nov 06 Python
Django框架静态文件处理、中间件、上传文件操作实例详解
Feb 29 Python
python 基于TCP协议的套接字编程详解
Jun 29 #Python
Python进阶:生成器 懒人版本的迭代器详解
Jun 29 #Python
简单了解Python matplotlib线的属性
Jun 29 #Python
Jacobi迭代算法的Python实现详解
Jun 29 #Python
Gauss-Seidel迭代算法的Python实现详解
Jun 29 #Python
python异步实现定时任务和周期任务的方法
Jun 29 #Python
python循环定时中断执行某一段程序的实例
Jun 29 #Python
You might like
php中静态类与静态变量用法的区别分析
2015/01/15 PHP
详解thinkphp实现excel数据的导入导出(附完整案例)
2016/12/29 PHP
PHP自定义序列化接口Serializable用法分析
2017/12/29 PHP
thinkphp3.2框架中where条件查询用法总结
2019/08/13 PHP
laravel Model 执行事务的实现
2019/10/10 PHP
JavaScript 以对象为索引的关联数组
2010/05/19 Javascript
悬浮数字的实现案例
2014/02/19 Javascript
移动端H5开发 Turn.js实现很棒的翻书效果
2016/06/20 Javascript
深入理解JavaScript中的块级作用域、私有变量与模块模式
2016/10/31 Javascript
使用vue打包时vendor文件过大或者是app.js文件很大的问题
2018/06/29 Javascript
echarts整合多个类似option的方法实例
2018/07/10 Javascript
vue组件之间数据传递的方法实例分析
2019/02/12 Javascript
vue 使用高德地图vue-amap组件过程解析
2019/09/07 Javascript
Vue中axios拦截器如何单独配置token
2019/12/27 Javascript
vue-quill-editor 自定义工具栏和自定义图片上传路径操作
2020/08/03 Javascript
在vue中使用jsonp进行跨域请求接口操作
2020/10/29 Javascript
Python 命令行参数sys.argv
2008/09/06 Python
python 设置文件编码格式的实现方法
2017/12/21 Python
python自动重试第三方包retrying模块的方法
2018/04/24 Python
Python判断一个list中是否包含另一个list全部元素的方法分析
2018/12/24 Python
记录Python脚本的运行日志的方法
2019/06/05 Python
Pandas删除数据的几种情况(小结)
2019/06/21 Python
PyQt5+Caffe+Opencv搭建人脸识别登录界面
2019/08/28 Python
浅谈tensorflow中Dataset图片的批量读取及维度的操作详解
2020/01/20 Python
Python中flatten( ),matrix.A用法说明
2020/07/05 Python
利用CSS3参考手册和CSS3代码生成工具加速来学习网页制
2012/07/11 HTML / CSS
css3中检验表单的required,focus,valid和invalid样式
2014/02/21 HTML / CSS
百度软件工程师职位
2013/02/14 面试题
技术学校毕业生求职信分享
2013/12/02 职场文书
销售业务员岗位职责
2014/01/29 职场文书
运动会稿件50字
2014/02/17 职场文书
QQ空间主人寄语大全
2014/04/12 职场文书
公司捐款倡议书
2014/05/14 职场文书
毕业生党员个人总结
2015/02/14 职场文书
清洁工个人总结
2015/03/04 职场文书
2016年寒假社会实践活动总结
2015/03/27 职场文书