Python3使用TCP编写一个简易的文件下载器功能


Posted in Python onMay 08, 2019

利用Python3来实现TCP协议,和UDP类似。UDP应用于及时通信,而TCP协议用来传送文件、命令等操作,因为这些数据不允许丢失,否则会造成文件错误或命令混乱。下面代码就是模拟客户端通过命令行操作服务器。客户端输入命令,服务器执行并且返回结果。

TCP(Transmission Control Protocol 传输控制协议):是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。

使用TCP编写一个简易的文件下载器要求:需编写文件下载器服务端和文件下载器客户端

服务器端代码:

import socket
import os
import threading
# 处理客户端请求下载文件的操作(从主线程提出来的代码)
def deal_client_request(ip_port, service_client_socket):
  # 连接成功后,输出“客户端连接成功”和客户端的ip和端口
  print("客户端连接成功", ip_port)
  # 接收客户端的请求信息
  file_name = service_client_socket.recv(1024)
  # 解码
  file_name_data = file_name.decode("utf-8")
  # 判断文件是否存在
  if os.path.exists(file_name_data):
    #输出文件字节数
    fsize = os.path.getsize(file_name_data)
    #转化为兆单位
    fmb = fsize/float(1024*1024)
    #要传输的文件信息
    senddata = "文件名:%s 文件大小:%.2fMB"%(file_name_data,fmb)
    #发送和打印文件信息
    service_client_socket.send(senddata.encode("utf-8"))
    print("请求文件名:%s 文件大小:%.2f MB"%(file_name_data,fmb))
    #接受客户是否需要下载
    options = service_client_socket.recv(1024)
    if options.decode("utf-8") == "y":
      # 打开文件
      with open(file_name_data, "rb") as f:
        # 计算总数据包数目
        nums = fsize/1024 
        # 当前传输的数据包数目
        cnum = 0
        while True:
          file_data = f.read(1024)
          cnum = cnum + 1
          jindu = cnum/nums*100
          print("当前已下载:%.2f%%"%jindu,end = "\r")
          if file_data:
            # 只要读取到数据,就向客户端进行发送
            service_client_socket.send(file_data)
          # 数据读完,退出循环
          else:
            print("请求的文件数据发送完成")
            break
    else:
      print("下载取消!")
  else:
    print("下载的文件不存在!")
  # 关闭服务当前客户端的套接字
  service_client_socket.close()
if __name__ == '__main__':
  # 把工作目录切换到data目录下
  os.chdir("./data")
  # 创建套接字
  tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  # 绑定端口号
  tcp_server_socket.bind(("", 3356))
  # 设置监听,将主动套接字变为被动套接字
  tcp_server_socket.listen(128)
  # 循环调用accept,可以支持多个客户端同时连接,和多个客户端同时下载文件
  while True:
    service_client_socket, ip_port = tcp_server_socket.accept()
    # 连接成功后打印套接字号
    #print(id(service_client_socket))
    # 创建子线程
    sub_thread = threading.Thread(target=deal_client_request, args=(ip_port, service_client_socket))
    # 启动子线程
    sub_thread.start()

客户端代码:

# 多任务文件下载器客户端
import socket
if __name__ == '__main__':
  # 创建套接字
  tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  # 和服务端连接
  server_ip = input("输入服务器IP:")
  tcp_client_socket.connect((server_ip, 3356))
  # 发送下载文件的请求
  file_name = input("请输入要下载的文件名:")
  # 编码
  file_name_data = file_name.encode("utf-8")
  # 发送文件下载请求数据
  tcp_client_socket.send(file_name_data)
  # 接收要下载的文件信息
  file_info = tcp_client_socket.recv(1024)
  # 文件信息解码
  info_decode = file_info.decode("utf-8")
  print(info_decode)
  #获取文件大小
  fileszie = float(info_decode.split(':')[2].split('MB')[0])
  fileszie2 = fileszie*1024
  # 是否下载?输入y 确认 输入q 取消
  opts = input("是否下载?(y 确认 q 取消)")
  if opts == 'q':
    print("下载取消!程序退出")
  else:
    print("正在下载 》》》")
    #向服务器确认正在下载
    tcp_client_socket.send(b'y')
    # 把数据写入到文件里
    with open("./" + file_name, "wb") as file:
      #目前接收到的数据包数目
      cnum = 0
      while True:
        # 循环接收文件数据
        file_data = tcp_client_socket.recv(1024)
        # 接收到数据
        if file_data:
          # 写入数据
          file.write(file_data)
          cnum = cnum+1
          jindu =cnum/fileszie2*100
          print("当前已下载:%.2f%%"%jindu,end = "\r")
        # 接收完成
        else:
          print("下载结束!")
          break
  # 关闭套接字
  tcp_client_socket.close()

运行窗口如下:

1)服务器端

Python3使用TCP编写一个简易的文件下载器功能

2)客户端

Python3使用TCP编写一个简易的文件下载器功能

注意:客户端和服务器端不要运行在IDLE中,直接使用终端运行。

总结

以上所述是小编给大家介绍的Python3使用TCP编写一个简易的文件下载器功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
Python中用Spark模块的使用教程
Apr 13 Python
Python通过DOM和SAX方式解析XML的应用实例分享
Nov 16 Python
Python错误提示:[Errno 24] Too many open files的分析与解决
Feb 16 Python
Python正则表达式教程之三:贪婪/非贪婪特性
Mar 02 Python
在centos7中分布式部署pyspider
May 03 Python
python 中random模块的常用方法总结
Jul 08 Python
Django在pycharm下修改默认启动端口的方法
Jul 26 Python
利用ImageAI库只需几行python代码实现目标检测
Aug 09 Python
tensorflow多维张量计算实例
Feb 11 Python
浅谈Python的方法解析顺序(MRO)
Mar 05 Python
python向企业微信发送文字和图片消息的示例
Sep 28 Python
Python基础之赋值,浅拷贝,深拷贝的区别
Apr 30 Python
详解Python的三种可变参数
May 08 #Python
Python数据类型之Tuple元组实例详解
May 08 #Python
基于腾讯云服务器部署微信小程序后台服务(Python+Django)
May 08 #Python
python中正则表达式与模式匹配
May 07 #Python
详解Python3网络爬虫(二):利用urllib.urlopen向有道翻译发送数据获得翻译结果
May 07 #Python
python对象与json相互转换的方法
May 07 #Python
python使用threading.Condition交替打印两个字符
May 07 #Python
You might like
php 需要掌握的东西 不做浮躁的人
2009/12/28 PHP
php设计模式 Template (模板模式)
2011/06/26 PHP
php中异常处理方法小结
2015/01/09 PHP
PHP magento后台无法登录问题解决方法
2016/11/24 PHP
jquery下组织javascript代码(js函数化)
2010/08/25 Javascript
extjs实现选择多表自定义查询功能 前台部分(ext源码)
2011/12/20 Javascript
基于javascipt-dom编程 table对象的使用
2013/04/22 Javascript
jquery的ajax和getJson跨域获取json数据的实现方法
2014/02/04 Javascript
Jquery图片延迟加载插件jquery.lazyload.js的使用方法
2014/05/21 Javascript
TypeScript 学习笔记之基本类型
2015/06/19 Javascript
JavaScript 封装一个tab效果源码分享
2015/09/15 Javascript
jquery获取easyui日期控件的值实现方法
2016/11/09 Javascript
JS基于onclick事件实现单个按钮的编辑与保存功能示例
2017/02/13 Javascript
整理关于Bootstrap排版的慕课笔记
2017/03/29 Javascript
浅谈Vue.js 1.x 和 2.x 实例的生命周期
2017/07/25 Javascript
vue-quill-editor富文本编辑器简单使用方法
2018/09/21 Javascript
vue+element模态框中新增模态框和删除功能
2019/06/11 Javascript
[47:55]Ti4第二日主赛事败者组 NaVi vs EG 1
2014/07/20 DOTA
[01:17]炒鸡美酒第四天TA暴走
2018/06/05 DOTA
python冒泡排序算法的实现代码
2013/11/21 Python
python使用tornado实现登录和登出
2018/07/28 Python
Python编译成.so文件进行加密后调用的实现
2019/12/23 Python
Python编程快速上手——Excel到CSV的转换程序案例分析
2020/02/28 Python
Python更换pip源方法过程解析
2020/05/19 Python
python如何设置静态变量
2020/09/07 Python
python如何对链表操作
2020/10/10 Python
当我正在为表建立索引的时候,SQL Server 会禁止对表的访问吗
2014/04/28 面试题
教师开学感言
2014/02/14 职场文书
销售人员职业生涯规划范文
2014/03/01 职场文书
幼师求职自荐信
2014/05/31 职场文书
2014县委书记四风对照检查材料思想汇报
2014/09/21 职场文书
员工工作自我评价
2014/09/26 职场文书
学校总务处领导干部个人对照检查材料思想汇报
2014/10/06 职场文书
2015高考寄语集锦
2015/02/27 职场文书
土建技术员岗位职责
2015/04/11 职场文书
详解在SQLPlus中实现上下键翻查历史命令的功能
2022/03/18 SQL Server