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中使用sys模板和logging模块获取行号和函数名的方法
Apr 15 Python
python编程实现归并排序
Apr 14 Python
Python随机生成手机号、数字的方法详解
Jul 21 Python
对Python的zip函数妙用,旋转矩阵详解
Dec 13 Python
Python参数解析模块sys、getopt、argparse使用与对比分析
Apr 02 Python
python实现最大子序和(分治+动态规划)
Jul 05 Python
Django单元测试工具test client使用详解
Aug 02 Python
Django项目之Elasticsearch搜索引擎的实例
Aug 21 Python
tensorboard 可以显示graph,却不能显示scalar的解决方式
Feb 15 Python
Python文字截图识别OCR工具实例解析
Mar 05 Python
五分钟学会怎么用Pygame做一个简单的贪吃蛇
Jan 06 Python
pytorch 实现多个Dataloader同时训练
May 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
Ha0k 0.3 PHP 网页木马修改版
2009/10/11 PHP
php检索或者复制远程文件的方法
2015/03/13 PHP
Thinkphp微信公众号支付接口
2016/08/04 PHP
Yii实现文章列表置顶功能示例
2016/10/18 PHP
PHP耦合设计模式实例分析
2018/08/08 PHP
写得不错的jquery table鼠标经过变色代码
2013/09/27 Javascript
javascript和jquery修改a标签的href属性
2013/12/16 Javascript
js 阻止子元素响应父元素的onmouseout事件具体实现
2013/12/23 Javascript
用IE重起计算机或者关机的示例代码
2014/03/10 Javascript
js实现上传图片预览的方法
2015/02/09 Javascript
RequireJS入门一之实现第一个例子
2015/09/30 Javascript
jQuery实现仿QQ空间装扮预览图片的鼠标提示效果代码
2015/10/30 Javascript
jQuery弹出下拉列表插件(实现kindeditor的@功能)
2016/08/16 Javascript
JavaScript实现垂直向上无缝滚动特效代码
2016/11/23 Javascript
angularjs+bootstrap菜单的使用示例代码
2017/03/07 Javascript
从零开始学习Node.js系列教程四:多页面实现数学运算的client端和server端示例
2017/04/13 Javascript
Vue.js 踩坑记之双向绑定
2018/05/03 Javascript
javascript和php使用ajax通信传递JSON的实例
2018/08/21 Javascript
解决vue init webpack 下载依赖卡住不动的问题
2020/11/09 Javascript
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 KG VS OG
2018/03/30 DOTA
pandas数值计算与排序方法
2018/04/12 Python
Python实现E-Mail收集插件实例教程
2019/02/06 Python
详解Python给照片换底色(蓝底换红底)
2019/03/22 Python
PyQt 实现使窗口中的元素跟随窗口大小的变化而变化
2019/06/18 Python
基于Django OneToOneField和ForeignKey的区别详解
2020/03/30 Python
CSS3条纹背景制作的实战攻略
2016/05/31 HTML / CSS
html+css实现自定义图片上传按钮功能
2019/09/04 HTML / CSS
幼儿园小班教学反思
2014/02/02 职场文书
网络管理专业求职信
2014/03/15 职场文书
机械工程及其自动化专业求职信
2014/08/08 职场文书
学校开学标语
2014/10/06 职场文书
本科毕业论文答辩稿
2015/06/23 职场文书
《老人与海鸥》教学反思
2016/02/16 职场文书
如何理解及使用Python闭包
2021/06/01 Python
MySQL 服务和数据库管理
2021/11/11 MySQL
Golang map映射的用法
2022/04/22 Golang