优化基于tcp,socket的ftp文件传输程序

原始程序:

template_ftp_server_old.py:

import socket
import json
import struct
import os
import time
import pymysql.cursorssoc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '192.168.31.111'
PORT = 4101
soc.bind((HOST,PORT))
port_str = str(PORT)
slice_id = int(port_str[:2]) - 20
ueX_str = 'user'
ue_id = int(port_str[3])
ueX_delay = ueX_str + str(ue_id) + '_delay' # 
ueX_v = ueX_str + str(ue_id) + '_v' #
ueX_loss = ueX_str + str(ue_id) + '_loss' #
soc.listen(5)
cnx = pymysql.connect(host='localhost', port=3306, user='root', password='123456', db='qt', charset='utf8mb4', connect_timeout=20)
cursor = cnx.cursor()# 上传函数
def uploading_file():ftp_dir = r'C:/Users/yinzhao/Desktop/ftp/ftpseverfile'  # 将传送的name.txt保存在该文件夹当中if not os.path.isdir(ftp_dir):os.mkdir(ftp_dir)head_bytes_len = conn.recv(4)  # 拿到struct后的头长度head_len = struct.unpack('i', head_bytes_len)[0]  # 取出真正的头长度# 拿到真正的头部内容conn.send("1".encode('utf8'))head_bytes = conn.recv(head_len)conn.send("1".encode('utf8'))# 反序列化后取出头head = json.loads(head_bytes)file_name = head['file_name']print(file_name)file_path = os.path.join(ftp_dir, file_name)data_len = head['data_len']received_size = 0data=b''#****************************************************旧程序问题1:一次发送最大数据量,越大传输速率越快*************************************max_size=65536*4while received_size < data_len:#************************************************旧程序问题2:在接收文件的循环中有大量统计 计算 操作数据库的代码,占用时间**************8#    ftp_v = open('E:\FTP_test\FTP_v.txt', 'w', encoding='utf-8')#  ftp_delay = open('E:\FTP_test\FTP_delay.txt', 'w', encoding='utf-8')if data_len - received_size > max_size:size = max_sizeelse:size = data_len - received_sizereceive_data = conn.recv(size)  # 接收文本内容#************************************************旧程序问题3:基于socket的tcp无需手动在服务端进行ack的操作,既若无需要服务端可以不手动回发消息**********# conn.send("1".encode('utf8'))#      delay=conn.recv(1024).decode('utf8')  # 接受时延#     conn.send(str(size).encode('utf-8'))  ##      v = conn.recv(1024).decode('utf8')  # 接受速率#      conn.send("1".encode('utf-8'))  ##      loss = conn.recv(1024).decode('utf8')  # 接受loss#      conn.send("1".encode('utf-8'))# print("delay:",delay)#      delay_float = float(delay)#     v_float = float(v)#     loss_float = float(loss)#     formatted_delay = "{:.2f}".format(delay_float)#      formatted_v = "{:.2f}".format(v_float)#    formatted_loss = "{:.2f}".format(loss_float)#    cursor.execute("UPDATE slice_v2 SET " + ueX_v +  "= %s," + ueX_delay +  "=%s, " + ueX_loss +  " =%s WHERE slice_id = %s", [str(formatted_v), str(formatted_delay), str(formatted_loss), slice_id])#    cnx.commit()data+=receive_datareceive_datalen = len(receive_data)received_size += receive_datalen# print(delay, file=ftp_delay)# print(v, file=ftp_v)#print(loss)# ftp_delay.close()#ftp_v.close()#***********************************************旧程序问题4:接收文件后进行组装,组装后统一写入,且在一个线程里,耗时*******************************with open(file_path, 'wb') as fw:fw.write(data)#  print("上传文件 " + str(file_name) + " 成功")#uploading_file()while True:encoding = 'utf-8'print('等待客户端连接...')conn, addr = soc.accept()print('客户端已连接:', addr)uploading_file()conn.close()

client_renew_old.py

# coding: UTF-8
import socket
import os
import struct
import json
import hashlib
import time# lient_soc.connect(('192.168.1.101', 8025))# 上传函数
def uploading_file(filepath,filename):client_soc = socket.socket()client_soc.connect(('192.168.31.111', 4101))try:encoding = 'utf-8'with open(filepath+filename, 'rb') as fr:#发送固定文件data = fr.read()head = {'data_len': len(data), 'file_name': filename}  # 自定义头head_bytes = json.dumps(head).encode('utf8')head_bytes_len = struct.pack('i', len(head_bytes))client_soc.send(head_bytes_len)client_soc.recv(20).decode('utf8')client_soc.send(head_bytes)client_soc.recv(20).decode('utf8')print(str(int(len(data))/1024)+'KB')# client_soc.send(data)max_size = 65536*4#max_size = 1024# 计算需要分成几个数据包发送num_packets = len(data) // max_sizeif len(data) % max_size > 0:num_packets += 1# 循环分批发送数据for i in range(num_packets):# 将延时、速率传到txt文件中start = i * max_sizeend = start + max_size# if(i==num_packets-1):#     end=len(data)packet = data[start:end]#从这里开始计时start = time.perf_counter()client_soc.sendall(packet)# client_soc.recv(1024).decode('utf8')#计算时间段# delay=float(time.perf_counter() - start)# s#v=round(len(packet)/1048576/delay,2)#MB/S# delay=int(delay*1000)#  print("延时:",delay)# print("传输速率:",v)#client_soc.send(str(delay).encode('utf8'))#      rev_size=client_soc.recv(1024).decode('utf8')#      loss=(len(packet)-int(rev_size))/len(packet)#   client_soc.send(str(v).encode('utf8'))#     client_soc.recv(1024).decode('utf8')#    client_soc.send(str(loss).encode('utf8'))#      client_soc.recv(1024).decode('utf8')#  print("丢包率:",loss)print("发送完毕")#uploading_file()except socket.error as e:print("发生错误:", str(e))finally:# 关闭连接client_soc.close()if __name__ == '__main__':filepath='C:/Users/yinzhao/Desktop/ftp/'filename='test.7z'i = 0while i<2 :encoding = "utf8"uploading_file(filepath,filename)i = i+1print(i)

目前有如下支持:

  1. 传输任何文件,若成功传输到服务器,不会损坏
  2. 传输速率:
    max_size =655364
    在这里插入图片描述
    max_size =65536
    8
    在这里插入图片描述

该代码经过测试,有如下问题与特性:
4. 一次发送最大数据量,越大传输速率越快。之前每次发送1024,现在修改为65536*4
5. 在接收文件的循环中有大量统计 计算 操作数据库的代码,占用时间
6. 基于socket的tcp无需手动在服务端进行ack的操作,既若无需要服务端可以不手动回发消息。原程序有大量手动进行确认的过程,占用大量时间
7. 完整接收文件后再进行组装,组装后统一写入,也可以改成接收一次包写入一次
8. 所有程序都在同一个线程里,可以将数据传输 统计 数据写入放在不同的程序里,提供程序执行速度

修改代码

import socket
import json
import struct
import os
import time
import pymysql.cursors
import datetime
import threadingsoc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '192.168.84.1'
PORT = 4101
soc.bind((HOST,PORT))
port_str = str(PORT)
slice_id = int(port_str[:2]) - 20
ueX_str = 'user'
ue_id = int(port_str[3])
ueX_delay = ueX_str + str(ue_id) + '_delay' # 
ueX_v = ueX_str + str(ue_id) + '_v' #
ueX_loss = ueX_str + str(ue_id) + '_loss' #
soc.listen(5)
cnx = pymysql.connect(host='localhost', port=3306, user='root', password='123456', db='qt', charset='utf8mb4', connect_timeout=20)
cursor = cnx.cursor()def up_to_mysql(v,delay,loss):delay_float = float(delay)v_float = float(v)loss_float = float(loss)formatted_delay = "{:.2f}".format(delay_float)formatted_v = "{:.2f}".format(v_float)formatted_loss = "{:.2f}".format(loss_float)cursor.execute("UPDATE slice_v2 SET " + ueX_v +  "= %s," + ueX_delay +  "=%s, " + ueX_loss +  " =%s WHERE slice_id = %s", [str(formatted_v), str(formatted_delay), str(formatted_loss), slice_id])cnx.commit()def write_file(file_path,data):with open(file_path, 'wb') as fw:fw.write(data)
# 上传函数
def uploading_file():ftp_dir = r'/home/lab/changeyaml/test'  # 将传送的name.txt保存在该文件夹当中if not os.path.isdir(ftp_dir):os.mkdir(ftp_dir)head_bytes_len = conn.recv(4)  # 拿到struct后的头长度head_len = struct.unpack('i', head_bytes_len)[0]  # 取出真正的头长度# 拿到真正的头部内容conn.send("1".encode('utf8'))head_bytes = conn.recv(head_len)conn.send("1".encode('utf8'))# 反序列化后取出头head = json.loads(head_bytes)file_name = head['file_name']print(file_name)file_path = os.path.join(ftp_dir, file_name)data_len = head['data_len']received_size = 0data=b''max_size=65536*8time_begin = datetime.datetime.now()time_rev_begin=datetime.datetime.now()time_rev_end=datetime.datetime.now()datasize_rev_last=0while received_size < data_len:if data_len - received_size > max_size:size = max_sizeelse:size = data_len - received_sizereceive_data = conn.recv(size)  # 接收文本内容  data+=receive_datareceive_datalen = len(receive_data)received_size += receive_datalentime_rev_end=datetime.datetime.now()time_gap=time_rev_end-time_rev_beginif time_gap.total_seconds()>=1 :time_rev_begin=time_rev_end# print((time_rev_end-time_rev_begin).total_seconds)data_rev_1s_KB=(received_size-datasize_rev_last)/1024# print("data:"+str(data_rev_1s_KB)+'KB')# print("speed:"+str(data_rev_1s_KB)+'KB/s')# print("speed:"+str(data_rev_1s_KB/1024)+'MB/s')delay= 1/(data_rev_1s_KB*1024/max_size)# print("delay:"+str(delay)+'s')delay_ms=delay*1000print("delay:"+str(delay)+'ms')datasize_rev_last=received_sizeup_mysql_thread = threading.Thread(target=up_to_mysql, args=(8*data_rev_1s_KB/1024, delay_ms,0))up_mysql_thread.start()time_end= datetime.datetime.now()time_transport=time_end-time_begintime_transport_s=time_transport.total_seconds()print("耗时:"+str(time_transport_s))data_len_KB=data_len/1024data_len_MB=data_len/(1024*1024)print("数据量:"+str(data_len_KB)+"KB")v_average=data_len_KB/time_transport_s# print("平均速度:"+str(v_average)+'KB/s')print("平均速度:"+str(data_len_MB/time_transport_s)+'MB/s')write_file_thread = threading.Thread(target=write_file, args=(file_path, data))write_file_thread.start()while True:encoding = 'utf-8'print('等待客户端连接...')conn, addr = soc.accept()print('客户端已连接:', addr)uploading_file()conn.close()
# coding: UTF-8
import socket
import os
import struct
import json
import hashlib
import time# 上传函数
def uploading_file(filepath,filename):client_soc = socket.socket()client_soc.connect(('192.168.1.21', 4101))try:encoding = 'utf-8'with open(filepath+filename, 'rb') as fr:#发送固定文件data = fr.read()head = {'data_len': len(data), 'file_name': filename}  # 自定义头head_bytes = json.dumps(head).encode('utf8')head_bytes_len = struct.pack('i', len(head_bytes))client_soc.send(head_bytes_len)client_soc.recv(20).decode('utf8')client_soc.send(head_bytes)client_soc.recv(20).decode('utf8')print(str(int(len(data))/1024)+'KB')# client_soc.send(data)max_size = 65536*8#max_size = 1024# 计算需要分成几个数据包发送num_packets = len(data) // max_sizeif len(data) % max_size > 0:num_packets += 1# 循环分批发送数据for i in range(num_packets):start = i * max_sizeend = start + max_size# if(i==num_packets-1):#     end=len(data)packet = data[start:end]#从这里开始计时start = time.perf_counter()client_soc.sendall(packet)print("发送完毕")#uploading_file()except socket.error as e:print("发生错误:", str(e))finally:# 关闭连接client_soc.close()if __name__ == '__main__':filepath='C:/Users/QD689/Desktop/ftp1.01/'filename='name.txt'i = 0while i<3 :encoding = "utf8"uploading_file(filepath,filename)uploading_file(filepath,filename)i = i+1print(i)

经过精简代码与多线程使用,以及合理配置每次发送数据量大小,ftp文件传输速率极大提高了,并且可以正确测算到速率与时延

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/17125.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

是面试官放水,还是公司实在是太缺人?这都没挂,华为原来这么容易进...

华为是大企业&#xff0c;是不是很难进去啊&#xff1f;” “在华为做软件测试&#xff0c;能得到很好的发展吗&#xff1f; 一进去就有9.5K&#xff0c;其实也没有想的那么难” 直到现在&#xff0c;心情都还是无比激动&#xff01; 本人211非科班&#xff0c;之前在字节和腾讯…

iphone卡在恢复模式怎么办?修复办法分享!

iPhone 卡在恢复屏幕问题是 iPhone 用户在软件更新或恢复期间的常见问题。如果你也遇到此问题&#xff0c;不要着急&#xff0c;接下来我们将探讨 iPhone 卡在恢复屏幕上的主要原因&#xff0c;以及如何轻松修复它。 iPhone卡在恢复屏幕问题上没有一个特别的原因&#xff0c;但…

数字资产管理是做什么的?

显然&#xff0c;单纯依靠人力来管理和盘点固定资产已经不能满足公司日益增长的需求。合理使用固定资产管理系统来帮助管理实物资产已经成为一种趋势。  有鉴于此&#xff0c;依靠信息技术的支持&#xff0c;选择RFID固定资产管理系统可以有效解决资产管理盘点等难题&#xf…

Maven右侧依赖Dependencies消失

项目右侧的Maven依赖Dependencies突然消失&#xff0c;项目中的注解都出现报错&#xff0c;出现这种情况应该是因为IDEA版本早于maven版本&#xff0c;重新检查项目中的Maven路径&#xff0c;选择File->Settings->搜索Maven&#xff0c;检查Maven home directory&#xf…

可以写进简历的kafka优化-----吞吐量提升一倍的方法

冲突 在看到项目工程里kafka 生产端配置的batch.size为500&#xff0c;而实际业务数据平均有1K大小的时候&#xff1b;我有点懵了。是的&#xff0c;这里矛盾了&#xff1b;莫非之前的作者认为这个batch.size是发送的条数&#xff0c;而不是kafka生产端内存缓存记录的大小&…

HackSudo2靶机 通关详解

环境配置 发现vmWare的kali扫不到virtualbox的靶机 网上找了挺久资料都没解决 索性全桥接上物理机了 信息收集 漏洞发现 扫个目录 都看了一眼 没什么有用的 然后回到file.php 感觉之前做过类似的靶场,猜测存在文件包含 随便传个file试试 确实有 考虑日志文件包含 之前看…

《2023中国开发者调查报告》探索2023中国开发者的技术创新与挑战:AIoT、云原生、国产数据库等领域的发展与前景

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

【AI之路】使用huggingface_hub优雅解决huggingface大模型下载问题

文章目录 前言一、Hugging face是什么&#xff1f;二、准备工作三、下载整个仓库或单个大模型文件1. 下载整个仓库2. 下载单个大模型文件 总结附录 前言 Hugging face 资源很不错&#xff0c;可是国内下载速度很慢&#xff0c;动则GB的大模型&#xff0c;下载很容易超时&#…

无涯教程-jQuery - load( url, data, callback)方法函数

load(url&#xff0c;data&#xff0c;callback)方法从服务器加载数据&#xff0c;并将返回的HTML放入匹配的元素中。 load( url, [data], [callback] ) - 语法 [selector].load( url, [data], [callback] ) 这是此方法使用的所有参数的描述- url - 包含请求发送到…

Meta AI研究团队新AI模型:Segment Anything图像分割任务

Segment Anything是Meta AI研究团队开发的一种新的AI模型&#xff0c;用于图像分割任务。该模型可以对任何图像中的任何对象进行分割&#xff0c;即将对象从图像中"剪切"出来。Segment Anything模型&#xff08;SAM&#xff09;是一个可提示的模型&#xff0c;可以根…

Vite+Vue3 开发UI组件库并发布到npm

一直对开源UI组件库比较感兴趣&#xff0c;摸索着开发了一套&#xff0c;虽然还只是开始&#xff0c;但是从搭建到发布这套流程基本弄明白了&#xff0c;现在分享给大家&#xff0c;希望对同样感兴趣的同学有所帮助。 目前我的这套名为hasaki-ui的组件库仅有两个组件&#xff0…

分布式异步任务处理组件(五)

节点上线和下线的逻辑-- 节点下线分为两种--心跳失败主动或被动和主节点断开连接&#xff0c;但是节点本身没有发生重启&#xff1b;第二种就是节点宕机重启--其实这两中情况下处理逻辑都是一样的&#xff0c;只是节点本身如果还能消费到kafka的时候可以继续执行任务但是不能从…

分布式异步任务处理组件(四)

基于zookeeper的HA集群设计思路-- 各个节点都可以消费任务&#xff0c;但是由主节点来投票&#xff1b;主节点通过注册zookeeper的临时节点来选举--主节点需要同步从节点的信息正常工作机制--各个节点&#xff08;包括主节点本身&#xff09;在执行任务之前询问主节点&#xf…

IntelliJ IDEA 2023.2 最新变化

主要更新 AI Assistant 限定访问 Ultimate 在此版本中&#xff0c;我们为 IntelliJ IDEA 引入了一项重要补充 – AI Assistant。 AI Assistant 当前具备一组由 AI 提供支持的初始功能&#xff0c;提供集成式 AI 聊天&#xff0c;可以完成一些任务&#xff0c;例如自动编写文档…

【计算机视觉】BLIP:统一理解和生成的自举多模态模型

文章目录 一、导读二、背景和动机三、方法3.1 模型架构3.2 预训练目标3.3 BLIP 高效率利用噪声网络数据的方法&#xff1a;CapFilt 四、实验4.1 实验结果4.2 各个下游任务 BLIP 与其他 VLP 模型的对比 一、导读 BLIP 是一种多模态 Transformer 模型&#xff0c;主要针对以往的…

5、Kubernetes核心技术 - Controller控制器工作负载

目录 一、Deployments - 控制器应用 二、Deployment升级回滚和弹性收缩 2.1、创建一个 1.14 版本的 pod 2.2、应用升级 2.3、查看升级状态 2.4、查看历史版本 2.5、应用回滚 2.6、弹性伸缩 三、StatefulSet - 有状态应用 四、DaemonSet - 守护进程 五、Job - 单次任…

Linux近两年高危漏洞修复过程记录

一、背景 2023年8月份&#xff0c;面对即将到来的“大运会”、“亚运会”&#xff0c;今年的例行安全护网阶段也将迎来新的挑战和时刻&#xff0c;为此相关部门发布了国家级实战攻防演练已进入紧急「备战」时刻&#xff01;这里我们主要说一下Linux OS层面的漏洞处理&#xff0…

spring5源码篇(12)——spring-mvc请求流程

spring-framework 版本&#xff1a;v5.3.19 文章目录 一、请求流程1、处理器映射器1.1、 RequestMappingHandlerMapping1.2、获取对应的映射方法1.3、添加拦截器 2、获取合适的处理器适配器3、通过处理器适配器执行处理器方法3.1、拦截器的前置后置3.2、处理器的执行3.2.1 参数…

React哲学——官方示例

在本篇技术博客中&#xff0c;我们将介绍React官方示例&#xff1a;React哲学。我们将深入探讨这个示例中使用的组件化、状态管理和数据流等核心概念。让我们一起开始吧&#xff01; 项目概览 React是一个流行的JavaScript库&#xff0c;用于构建用户界面。React的设计理念是…

QuantMania!《快乐机器学习》和《Python 从入门到入迷》作者,FRM,CAIA

王的机器主理人 王圣元 (FRM, CAIA) 某加密货币公司 Head of Quant 冬海集团 SeaMoney 建模负责人 八方咨询 量化总监 新加坡国立大学金融数学硕士 新加坡国立大学量化金融学士 《快乐机器学习》的作者 《Python 从入门到入迷》的作者 第一本书 《快乐机器学习》 第二本书《Pyt…