python实现简单的文件传输程序-TCP

本文介绍了一个使用Python3.7.3实现的简单TCP文件传输程序。程序允许服务端与客户端建立TCP连接,实现文件的下载,包括传输元数据和进度显示。客户端通过输入文件名请求下载,服务端接收请求并查找文件发送。传输过程中,文件头信息经过序列化、打包、发送和接收后反序列化。文章还讨论了序列化和打包在跨网络传输中的作用。
摘要由CSDN通过智能技术生成

layout: post
title: “python实现简单的文件传输程序-TCP”
date: 2019-05-18
description: “一次计网作业,分UDP和TCP”
tag: python


说明

  • 本程序仅在python3.7.3下测试无错

TCP

因为代码比较短所以直接贴了,程序实现了如下功能:

  • 服务端与单个客户端建立一条TCP连接,客户端从服务端的目录下下载指定文件到所在目录下
  • 传输文件的大小,修改日期等管理元数据
  • 显示传输的进度条
  • 多线程同时与多个客户端建立连接
  • 更友好的用户界面
  • 客户端的上传功能
运行过程
  1. 在电脑A上打开服务端程序,将ip和端口(若不提示端口被占用则无需修改)改为你自己的,运行,同时将想要被下载的文件放在程序同一目录下;
  2. 在电脑B上打开客户端程序,将ip和端口改为服务端的ip和端口,运行,输入想要下载文件名+回车,等待下载完成,可在程序同一目录下看到下载的文件。
实现过程

首先建立TCP连接,然后客户端向服务端 send 文件名,发出下载请求,服务端查找本地目录,若找到该文件,则发送,发送具体过程为先发送文件头大小,再发送文件头(即文件名,大小等管理元数据),最后发送文件内容。若找不到文件,则发送文件头大小为0,客户端通过收到的文件头大小来判断是否能下载该文件。

文件头用字典定义如下:

#文件头
header = {
   
    'file_name': file_name,
    'file_size': os.path.getsize(file_path),
    'file_ctime': os.path.getctime(file_path),
    'file_atime': os.path.getatime(file_path),
    'file_mtime': os.path.getmtime(file_path)
}

文件头的传输过程:序列化dumps->打包pack->发送send->接受recv->解包unpack->反序列化loads

为什么要进行这一系列操作?因为在网络上传输的是二进制的数据,而我们的文件头定义为一个字典。

关于序列化
  • 序列化:把不可传输的对象转换为可存储在磁盘中的或可在网络中传输的数据的过程
  • 反序列化:把在磁盘中储存的,或者网络中传送的持久化数据转换为对象

程序使用的相关模块是pickle或者cPickle,pickle.dumps()方法可以把任意对象序列化返回一个字符串,而pickle.loads()则可以反序列化重新得到header字典。但是用pickle序列化的数据只能被python识别,并且可能不同版本的python互相都不兼容,如果要在不同的编程语言之间传递对象,就必须序列化为标准格式,如XML或JSON,需要用json等模块,具体内容在此不详细叙述。

关于打包

其实就是把要发送的数据按已定义的格式拼接起来形成数据包来发送。

相关模块是struct,定义数据包格式如下:

header_struct = struct.Struct('i1024s')
data_struct = struct.Struct('1024s')

相当于C语言中的:

struct header_struct {
    int i;
    //1024个B
}

所用的struct格式符:

格式符 Python Type 字节数
i,I(大写i),l(小写L) intenger 4
s bytes 1

而从文件中读取的数据本身就是二进制,所以可以直接发送。

客户端
import socket
import struct
import pickle
import time
import os

server_ip = '127.0.0.1'
server_port = 5200
file_dir = os.path.dirname(os.path.abspath(__file__))
header_struct = struct
  • 13
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值