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网络编程学习笔记(八):XML生成与解析(DOM、ElementTree)
Jun 09 Python
python列表操作之extend和append的区别实例分析
Jul 28 Python
使用Python绘制图表大全总结
Feb 11 Python
深入理解Python3中的http.client模块
Mar 29 Python
Python字典实现简单的三级菜单(实例讲解)
Jul 31 Python
使用 Python 实现简单的 switch/case 语句的方法
Sep 17 Python
Pytorch之view及view_as使用详解
Dec 31 Python
python模拟实现斗地主发牌
Jan 07 Python
python logging设置level失败的解决方法
Feb 19 Python
Python argparse模块使用方法解析
Feb 20 Python
Python 通过爬虫实现GitHub网页的模拟登录的示例代码
Aug 17 Python
关于pycharm 切换 python3.9 报错 ‘HTMLParser‘ object has no attribute ‘unescape‘ 的问题
Nov 24 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
来自phpguru得Php Cache类源码
2010/04/15 PHP
php数组比较实现查找连续数的方法
2015/07/29 PHP
php构造方法中析构方法在继承中的表现
2016/04/12 PHP
Laravel学习基础之migrate的使用教程
2017/10/11 PHP
总结PHP代码规范、流程规范、git规范
2018/06/18 PHP
JavaScript高级程序设计 阅读笔记(四) ECMAScript中的类型转换
2012/02/27 Javascript
JS获取后台Cookies值的小例子
2013/03/04 Javascript
javascript间隔刷新的简单实例
2013/11/14 Javascript
javascript中的原型链深入理解
2014/02/24 Javascript
jQuery学习笔记之 Ajax操作篇(二) - 数据传递
2014/06/23 Javascript
jquery ui resize 中border-box的bug修正
2015/04/26 Javascript
node.js下LDAP查询实例分享
2015/09/30 Javascript
AngularJS 应用身份认证的技巧总结
2016/11/07 Javascript
Angularjs中使用指令绑定点击事件的方法
2017/03/30 Javascript
JavaScript Array对象基本方法详解
2019/09/03 Javascript
jquery实现垂直手风琴导航栏
2020/02/18 jQuery
jQuery编写QQ简易聊天框
2020/08/27 jQuery
编写简单的Python程序来判断文本的语种
2015/04/07 Python
Python基于Tkinter的HelloWorld入门实例
2015/06/17 Python
浅谈django model的get和filter方法的区别(必看篇)
2017/05/23 Python
Tensorflow实现卷积神经网络用于人脸关键点识别
2018/03/05 Python
使用python编写监听端
2018/04/12 Python
浅析python参数的知识点
2018/12/10 Python
Expedia泰国:预订机票、酒店和旅游包(航班+酒店)
2016/09/27 全球购物
idealfit英国:世界领先的女性健身用品和运动衣物品牌
2017/11/25 全球购物
运动会解说词50字
2014/01/18 职场文书
教师档案管理制度
2014/01/23 职场文书
信息总监管理职责范本
2014/03/08 职场文书
大学生毕业评语
2014/12/31 职场文书
搞笑老公保证书
2015/02/26 职场文书
党员自我评价2015
2015/03/03 职场文书
朋友聚会开场白
2015/06/01 职场文书
导游词之黄帝陵景区
2019/09/16 职场文书
python基础之文件处理知识总结
2021/05/23 Python
Java spring单点登录系统
2021/09/04 Java/Android
《帝国时代4》赛季预告 新增内容编译器可创造地图
2022/04/03 其他游戏