Python利用tcp_socket实现简单文件下载功能

文章目录

  • Python利用tcp_socket实现简单文件下载功能
    • 一、客户端
    • 二、服务端
    • 三、成果展示
      • 3.1 创建测试文件
      • 3.2 下载测试文件
      • 3.3 查看下载文件
    • 四、文件下载器升级版
      • 4.1、更新公告
        • 4.1.1 升级版客户端代码
        • 4.1.2 升级版服务端代码
      • 4.2 升级版成果展示
    • 问题处理

一、客户端

客户端比较好写一点,我们先来实现客户端的功能

客户端实现原理

  • 创建tcp_socket, 通过IP地址与端口连接服务端
  • 通过input函数获取filename并发送到服务端
  • 接收到来自服务端发来的文件内容
  • 判断发来的文件内容是否为空,如果为空,代表服务端发送异常,停止创建文件
  • 如果不为空,创建新文件,写入服务端发来的内容

服务端发送的都是byte类型的数据,所以我们用wb方式写入文件

代码如下:

import os
import socketdef main():tcp_download_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)tcp_download_socket.connect((b'127.0.0.1',7788))while True:file_name=input('请输入要下载的文件内容')tcp_download_socket.send(file_name.encode('utf-8'))  #发送filenamerecv_data=tcp_download_socket.recv(1024*1024)  #最大限制1MBprint('开始写入文件---')if recv_data:with open('new_'+ file_name,'bw') as doenload_file:doenload_file.write(recv_data)doenload_file.close()if os.path.isfile('new_'+ file_name):print('下载文件成功')answer = input("是否下载其他文件")if answer == 'y' or answer == 'Y':continueelse:breakelse:print("服务端不存在该文件,请检查后重试")continueif __name__ == '__main__':main()

二、服务端

客户端没问题了,我们实现一下服务端

服务端实现原理:

  • 创建服务端socket,并绑定7788端口
  • 开始持续监听7788端口,此时阻塞
  • 客户端发送连接请求,连接客户端成功,服务端解阻塞
  • 接收到客户端发送的filename,调用os模块判断文件是否存在
  • 若存在,使用with以rb方式查看文件,并赋值data=file.read(),向客户端发送data
  • 若不存在文件,不返回任何内容,此时服务端也会做出相应动作

服务端代码如下:

import socket
import osdef main():server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)server_socket.bind(('',7788))server_socket.listen(128)  #最多允许128个客户端同时连接while True:print("===开始接收请求===")new_server_socket,client_addr=server_socket.accept()print(f'客户端已建立连接,客户端地址是{client_addr}')while True:if new_server_socket:file_name=new_server_socket.recv(1024)  #接收filenameif os.path.isfile(file_name):with open(file_name,'rb') as file:data=file.read()new_server_socket.send(data)else:print("文件不存在")new_server_socket.close()breakelse:print("客户端关闭连接")breakif __name__ == "__main__" :main()

三、成果展示

为了方便,我们用pycharm来演示

3.1 创建测试文件

aaa.txt

3.2 下载测试文件

客户端操作如下:

服务端响应如下:

3.3 查看下载文件

四、文件下载器升级版

之前的文件下载虽然实现了下载的功能,但是如果是陌生的服务器,我们并不知道对方服务器的文件到底有哪些,于是我就升级了一下程序

4.1、更新公告

  • 服务端会首先向客户端发送程序所在目录的文件列表,以供客户端下载
  • 使用logging模块,打印标准日志,更易观察
  • 修复已知BUG

代码如下:

4.1.1 升级版客户端代码

import ast
import logging
import os
import socket
from prettytable import PrettyTableu = PrettyTable(['文件名', '文件大小'])Format = logging.Formatter('%(levelname)s  %(asctime)s %(filename)s  %(funcName)s %(message)s ')
logger = logging.getLogger()
logger.setLevel('DEBUG')
console_handle = logging.StreamHandler()
console_handle.setLevel(level='INFO')
console_handle.setFormatter(Format)
logger.addHandler(console_handle)def get_file_info():tcp_download_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_download_socket.connect((b'127.0.0.1', 7789))tcp_download_socket.send('getfile'.encode('utf-8'))filelist = tcp_download_socket.recv(1024)# 使用ast模块的literal_eval,将str转换为dictfile_info = ast.literal_eval(filelist.decode('utf-8'))# 通过for循环与preaytable模块,创建表格for key, value in file_info.items():u.add_row([key, str(value)])print(u)tcp_download_socket.close()def main():print('目标服务器文件列表如下')get_file_info()while True:tcp_download_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_download_socket.connect((b'127.0.0.1', 7788))print('\n')file_name = input('请输入要下载的文件内容:')tcp_download_socket.send(file_name.encode('utf-8'))  # 发送filenamerecv_data = tcp_download_socket.recv(1024 * 1024)  # 最大限制1MBlogger.info('开始写入文件---')if recv_data:if recv_data.decode('utf-8') == 'filenotexists':logger.error('file not exists')tcp_download_socket.close()continueelse:with open('new_' + file_name, 'bw') as doenload_file:doenload_file.write(recv_data)doenload_file.close()if os.path.isfile('new_' + file_name):logger.info('下载文件成功')tcp_download_socket.close()answer = input("是否下载其他文件")if answer == 'y' or answer == 'Y':continueelse:breakif __name__ == '__main__':main()

4.1.2 升级版服务端代码

import socket
import os
import logging
import threadingFormat = logging.Formatter('%(levelname)s  %(asctime)s %(filename)s %(funcName)s %(message)s ')
logger = logging.getLogger()
logger.setLevel('DEBUG')
console_handle = logging.StreamHandler()
console_handle.setLevel(level='INFO')
console_handle.setFormatter(Format)
logger.addHandler(console_handle)def send_file_info():while True:logger.info("===开始接收发送信息请求===")file_info = {}files = os.listdir('.')for file in files:# 获取文件大小,因为文件太小多以取两位小数file_size = round(os.path.getsize(file) / 1024, 3)file_info[file] = f'{file_size}kb'tcp_getlist_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 为避免端口冲突,使用其他端口tcp_getlist_socket.bind(('', 7789))tcp_getlist_socket.listen(128)logger.info('创建发送文件信息套接字')new_server_socket, client_addr = tcp_getlist_socket.accept()logger.info(f'接收信息客户端已建立连接,客户端地址是{client_addr}')new_server_socket.send(str(file_info).encode('utf-8'))logger.info('成功发送客户端信息')# new_server_socket.close()# tcp_getlist_socket.close()logger.info('关闭发送文件信息套接字')def main():# 创建send_file线程t1 = threading.Thread(target=send_file_info)t1.start()server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind(('', 7788))server_socket.listen(128)  # 最多允许128个客户端同时连接while True:logger.info("===开始接收下载请求===")new_server_socket, client_addr = server_socket.accept()logger.info(f'下载客户端已建立连接,客户端地址是{client_addr}')while True:if new_server_socket:file_name = new_server_socket.recv(1024).decode('utf-8')  # 接收filenameif os.path.isfile(file_name):with open(file_name, 'rb') as file:data = file.read()logger.info('发送文件{0}内容'.format(file_name))new_server_socket.send(data)new_server_socket.close()breakelse:logger.error("文件不存在")new_server_socket.send('filenotexists'.encode('utf8'))new_server_socket.close()breakelse:print("客户端关闭连接")breakif __name__ == "__main__":main()

4.2 升级版成果展示

服务端启动服务开始监听

客户端启动:
首先会打印服务端文件内容,以列表形式展示

输入下载文件名 aaa.txt


成功下载

服务端日志如下:
很明显看到我是建立了两次链接的,前一次是为了接受文件列表信息

当文件不存在时,服务端会发送 file not exists 消息,客户端收到消息后,做出相应动作

重新填写正确文件,下载成功

问题处理

1、发送文件函数只发送一次,当客户端第二次启动时,会报连接失败
原因:发送文件函数只调用一次,第二次客户端连接时,函数socket实际上已关闭
解决方法:
给函数加上while True,去掉close方法,创建多线程

    # 创建send_file线程t1 = threading.Thread(target=send_file_info)t1.start()

Python利用tcp_socket实现文件下载器相关推荐

  1. python文件下载器代码_GitHub - applechi/pythonCollection: python代码集合(文件下载器、pdf合并、极客时间专栏下载、掘金小册下载、新浪微博爬虫等)...

    json2mysql 这次更新了将一个json文件中的数据导入到mysql的脚本. 是用nodejs写的. 对应的文件是tomysql.js 有兴趣的同志可以研究下. pythonCollection ...

  2. python写一个文件下载器_Python3使用TCP编写一个简易的文件下载器

    原标题:Python3使用TCP编写一个简易的文件下载器 利用Python3来实现TCP协议,和UDP类似.UDP应用于及时通信,而TCP协议用来传送文件.命令等操作,因为这些数据不允许丢失,否则会造 ...

  3. python类加载器_利用Python反序列化运行加载器实现免杀

    前言 前几天在看Python的shellcode加载器,在网上找了一个,结果加载器自身就过不了火绒,测试发现是火绒对关键语句进行了识别. 所以我们要想办法去掉加载器中明显的特征. 原理及实现 在绕过静 ...

  4. TCP文件下载器(Python)

    使用TCP编写一个文件下载器,分为客户端和服务器,此博客为上一篇的延伸,增加了文件读写编程. 下载器服务器程序: import socketdef send_file_client(new_clien ...

  5. php5.5 反序列化利用工具_利用Python反序列化运行加载器实现免杀

    前言 前几天在看Python的shellcode加载器,在网上找了一个,结果加载器自身就过不了火绒,测试发现是火绒对关键语句进行了识别. 所以我们要想办法去掉加载器中明显的特征. 原理及实现 在绕过静 ...

  6. python写一个文件下载器_python使用tcp实现一个简单的下载器

    上一篇中介绍了tcp的流程,本篇通过写一个简单的文件下载器程序来巩固之前学的知识. 文件下载器的流程如下: 客户端: 输入目标服务器的ip和port 输入要下载文件的名称 从服务器下载文件保存到本地 ...

  7. python高级 笔记 08 (TCP服务器增强 + 文件下载器 案例 综合应用)

    TCP服务器接受客户端多条信息 主要方式: 通过在接受信息,等待数据 recv前增加一个死循环 import sockettcp_client_socket = socket.socket(socke ...

  8. 网络 #TCP #UDP #文件下载器 #网络通信

    网络 网络基础 1)IP地址 1>查看网卡信息 2>IP地址分类 3>私有IP 2)端口 1>端口的分类(部分) 1.知名端口 2.动态端口 2>查看端口号 3)sock ...

  9. python多进程断点续传分片下载器

    python多进程断点续传分片下载器 标签:python 下载器 多进程 因为爬虫要用到下载器,但是直接用urllib下载很慢,所以找了很久终于找到一个让我欣喜的下载器.他能够断点续传分片下载,极大提 ...

最新文章

  1. php跳过当前后续代码,PHP用continue跳过本次循环中剩余代码的注意点
  2. 810D - 如何写学术论文
  3. Oracle 登录时错误: ORA-01017: invalid username/password; logon denied
  4. Java MySql 连接数据库
  5. LAMP介绍,Apache安装细节过程
  6. Lync-技巧-2.启用-用户-启用-语音-设置-线路URI
  7. 【转】删除已经存在的 TFS Workspace
  8. oracle数据泵导入很慢,impdp导入效率的问题
  9. CSS实现垂直居中布局
  10. C# Attribute(中)——Attribute本质论
  11. java根据系统时间拼凑文件名字
  12. ros melodic控制真实机械臂之openmanipulator参考
  13. css制作tips提示框,气泡框,制作三角形
  14. 计划任务,机器码与注册码,Web服务
  15. valgrind 报告 ecpg内存泄露 (二)
  16. android4.4 adb工具包,Android ADB工具
  17. 使用 Chrome 浏览器截取网页长图
  18. 安装pyHive报错
  19. 播放音乐的html代码,音乐播放器-html代码
  20. 漫反射贴图与镜面光贴图

热门文章

  1. PHP QRCODE 彩色二维码
  2. 联想笔记本怎么进入pe系统_联想笔记本电脑无法进入PE
  3. 第五章 项目沟通与冲突管理
  4. 车险保单在线OCR识别,字段很全,可以可以
  5. 在线 ocr 文字识别 和 图片色值选取
  6. 2016年9月16日 总结
  7. html 删除icon图标素材,精选Dribbble图标Icon素材集(2013年春季版50+)
  8. 软件项目工作量估算之软件复用程度分析
  9. 共享文档服务器iops,云服务器iops
  10. python求1~100的和