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通过RabbitMQ服务器实现交换机功能的实例教程
Jun 29 Python
用Python实现KNN分类算法
Dec 22 Python
浅谈Python2获取中文文件名的编码问题
Jan 09 Python
Python数据可视化之画图
Jan 15 Python
Python使用sax模块解析XML文件示例
Apr 04 Python
Python3远程监控程序的实现方法
Jul 15 Python
TensorFlow tf.nn.max_pool实现池化操作方式
Jan 04 Python
jupyter notebook读取/导出文件/图片实例
Apr 16 Python
django 利用Q对象与F对象进行查询的实现
May 15 Python
详解python metaclass(元类)
Aug 13 Python
python按照list中字典的某key去重的示例代码
Oct 13 Python
利用Python实现自动扫雷小脚本
Dec 17 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 获取远程网页内容的代码(fopen,curl已测)
2011/06/06 PHP
PHP中加密解密函数与DES加密解密实例
2014/10/17 PHP
php和vue配合使用技巧和方法
2019/05/09 PHP
解放web程序员的输入验证
2006/10/06 Javascript
jquery JSON的解析方式
2009/07/25 Javascript
表单的焦点顺序tabindex和对应enter键提交
2013/01/04 Javascript
JS分页效果示例
2013/10/11 Javascript
Javascript数组与字典用法分析
2014/12/13 Javascript
javascript实现unicode与ASCII相互转换的方法
2015/12/10 Javascript
很不错的两款Bootstrap Icon图标选择组件
2016/01/28 Javascript
jQuery实现文档树效果
2017/02/20 Javascript
vue 和vue-touch 实现移动端左右导航效果(仿京东移动站导航)
2017/04/22 Javascript
npm 更改默认全局路径以及国内镜像的方法
2018/05/16 Javascript
如何将HTML字符转换为DOM节点并动态添加到文档中详解
2018/08/19 Javascript
微信小程序之裁剪图片成圆形的实现代码
2018/10/11 Javascript
基于html+css+js实现简易计算器代码实例
2020/02/28 Javascript
python局域网ip扫描示例分享
2014/04/03 Python
使用Python多线程爬虫爬取电影天堂资源
2016/09/23 Python
深入理解Django的自定义过滤器
2017/10/17 Python
python编写分类决策树的代码
2017/12/21 Python
Python logging管理不同级别log打印和存储实例
2018/01/19 Python
基于Python函数和变量名解析
2019/07/19 Python
浅谈Pytorch中的自动求导函数backward()所需参数的含义
2020/02/29 Python
基于Python-Pycharm实现的猴子摘桃小游戏(源代码)
2021/02/20 Python
详解移动端Html5页面中1px边框的几种解决方法
2018/07/24 HTML / CSS
美国庭院家具购物网站:AlphaMarts
2019/04/10 全球购物
MYPROTEIN澳大利亚官方网站:欧洲运动营养品牌
2019/06/26 全球购物
LINUX下线程,GDI类的解释
2012/04/17 面试题
工地资料员岗位职责
2013/12/31 职场文书
市三好学生主要事迹
2014/01/28 职场文书
竞选班干部演讲稿400字
2014/08/20 职场文书
2015年公共机构节能宣传周活动总结
2015/03/26 职场文书
乡镇保密工作承诺书
2015/05/04 职场文书
从事会计工作年限证明
2015/06/23 职场文书
七年级作文之环保作文
2019/10/17 职场文书
MySQL8.0.24版本Release Note的一些改进点
2021/04/22 MySQL