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一键升级所有pip package的方法
Jan 16 Python
Python中几种导入模块的方式总结
Apr 27 Python
python 定义给定初值或长度的list方法
Jun 23 Python
Linux下python制作名片示例
Jul 20 Python
神经网络相关之基础概念的讲解
Dec 29 Python
Python面向对象之类和实例用法分析
Jun 08 Python
Python中的asyncio代码详解
Jun 10 Python
pytorch中tensor张量数据类型的转化方式
Dec 31 Python
在tensorflow中设置使用某一块GPU、多GPU、CPU的操作
Feb 07 Python
基于TensorBoard中graph模块图结构分析
Feb 15 Python
2020最新pycharm汉化安装(python工程狮亲测有效)
Apr 26 Python
Python魔术方法专题
Jun 19 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函数file_get_contents超时处理的方法详解
2013/06/03 PHP
基于JQuery+PHP编写砸金蛋中奖程序
2015/09/08 PHP
Javascript 自适应高度的Tab选项卡
2011/04/05 Javascript
Jquery通过Ajax方式来提交Form表单的具体实现
2013/11/07 Javascript
开发中可能会用到的jQuery小技巧
2014/03/07 Javascript
js使用for循环与innerHTML获取选中tr下td值
2014/09/26 Javascript
JavaScript分秒倒计时器实现方法
2015/02/02 Javascript
使用JavaScript刷新网页的方法
2015/06/04 Javascript
详解jQuery移动页面开发中的ui-grid网格布局使用
2015/12/03 Javascript
javascript html实现网页版日历代码
2016/03/08 Javascript
IOS中safari下的select下拉菜单文字过长不换行的解决方法
2016/09/26 Javascript
js中Number数字数值运算后值不对的解决方法
2017/02/28 Javascript
使用Browserify来实现CommonJS的浏览器加载方法
2017/05/14 Javascript
JavaScript Date对象应用实例分享
2017/10/30 Javascript
Node.js 使用axios读写influxDB的方法示例
2018/10/26 Javascript
js prototype和__proto__的关系是什么
2019/08/23 Javascript
JS通用方法触发点击事件代码实例
2020/02/17 Javascript
Python迭代器和生成器介绍
2015/03/06 Python
python3对拉勾数据进行可视化分析的方法详解
2019/04/03 Python
Python Django框架url反向解析实现动态生成对应的url链接示例
2019/10/18 Python
python 实现视频 图像帧提取
2019/12/10 Python
centos7中安装python3.6.4的教程
2019/12/11 Python
pytorch 准备、训练和测试自己的图片数据的方法
2020/01/10 Python
python 实时调取摄像头的示例代码
2020/11/25 Python
新媒传信软件测试面试题
2013/02/24 面试题
教育学专业毕业生的自我鉴定
2013/11/26 职场文书
公司开业庆典主持词
2014/03/21 职场文书
《数星星的孩子》教学反思
2014/04/11 职场文书
护理专业自荐书
2014/06/04 职场文书
群众路线个人自我剖析材料
2014/10/07 职场文书
医德医风个人工作总结2014
2014/11/14 职场文书
门卫岗位职责
2015/02/09 职场文书
小学中队委竞选稿
2015/11/20 职场文书
python 统计代码耗时的几种方法分享
2021/04/02 Python
html5移动端禁止长按图片保存的实现
2021/04/20 HTML / CSS
利用Apache Common将java对象池化的问题
2022/06/16 Servers