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 相关文章推荐
记录Django开发心得
Jul 16 Python
Python实现基于HTTP文件传输实例
Nov 08 Python
Python实现处理管道的方法
Jun 04 Python
linux平台使用Python制作BT种子并获取BT种子信息的方法
Jan 20 Python
python生成不重复随机数和对list乱序的解决方法
Apr 09 Python
python 实现selenium断言和验证的方法
Feb 13 Python
Python自动化之数据驱动让你的脚本简洁10倍【推荐】
Jun 04 Python
Python字典对象实现原理详解
Jul 01 Python
Python 获取命令行参数内容及参数个数的实例
Dec 20 Python
Django中的session用法详解
Mar 09 Python
如何在django中实现分页功能
Apr 22 Python
python在协程中增加任务实例操作
Feb 28 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.NET的入门教程
2006/10/09 PHP
php intval的测试代码发现问题
2008/07/27 PHP
JoshChen_php新手进阶高手不可或缺的规范介绍
2013/08/16 PHP
php实现Mysql简易操作类
2015/10/11 PHP
Zend Framework教程之Zend_Helpers动作助手ViewRenderer用法详解
2016/07/20 PHP
php指定长度分割字符串str_split函数用法示例
2017/01/30 PHP
document.compatMode介绍
2009/05/21 Javascript
jquery.validate使用攻略 第一部
2010/07/01 Javascript
让jQuery Mobile不显示讨厌loading界面的方法
2014/02/19 Javascript
jquery简单实现网页层的展开与收缩效果
2015/08/07 Javascript
JS简单模拟触发按钮点击功能的方法
2015/11/30 Javascript
图片懒加载插件实例分享(含解析)
2017/01/09 Javascript
微信小程序 开发MAP(地图)实例详解
2017/06/27 Javascript
vue教程之toast弹框全局调用示例详解
2020/08/24 Javascript
jQuery中$原理实例分析
2018/08/13 jQuery
详解React服务端渲染从入门到精通
2019/03/28 Javascript
详解基于mpvue微信小程序下载远程图片到本地解决思路
2019/05/16 Javascript
浅谈layui 数据表格前后台传值的问题
2019/09/12 Javascript
react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面
2019/11/12 Javascript
es6中let和const的使用方法详解
2020/02/24 Javascript
[48:30]LGD vs infamous Supermajor小组赛D组 BO3 第一场 6.3
2018/06/04 DOTA
[01:06:12]VP vs NIP 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
python获取当前用户的主目录路径方法(推荐)
2017/01/12 Python
python dataframe向下向上填充,fillna和ffill的方法
2018/11/28 Python
解决python3.5 正常安装 却不能直接使用Tkinter包的问题
2019/02/22 Python
实例详解Python模块decimal
2019/06/26 Python
python+jinja2实现接口数据批量生成工具
2019/08/28 Python
python 弧度与角度互转实例
2020/04/15 Python
Virtualenv 搭建 Py项目运行环境的教程详解
2020/06/22 Python
中学生操行评语
2014/04/24 职场文书
2014市国税局对照检查材料思想汇报
2014/09/23 职场文书
网络销售员岗位职责
2015/04/11 职场文书
2015年度个人业务工作总结
2015/04/27 职场文书
开学典礼致辞
2015/07/29 职场文书
《槐乡的孩子》教学反思
2016/02/20 职场文书
根德5570型九灯四波段立体声收音机是电子管收音机的楷模 ? 再论5570
2022/04/05 无线电