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 相关文章推荐
Cpy和Python的效率对比
Mar 20 Python
Python将阿拉伯数字转换为罗马数字的方法
Jul 10 Python
Python编程中NotImplementedError的使用方法
Apr 21 Python
Python实现简单查找最长子串功能示例
Feb 26 Python
python 中xpath爬虫实例详解
Aug 26 Python
python中树与树的表示知识点总结
Sep 14 Python
Python实现字符串中某个字母的替代功能
Oct 21 Python
Python3和PyCharm安装与环境配置【图文教程】
Feb 14 Python
Python高并发解决方案实现过程详解
Jul 31 Python
详解python with 上下文管理器
Sep 02 Python
Python+OpenCV图像处理——图像二值化的实现
Oct 24 Python
PyCharm 解决找不到新打开项目的窗口问题
Jan 15 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 命名空间实例说明
2011/01/27 PHP
PHP SESSION机制的理解与实例
2019/03/22 PHP
6个常见的 PHP 安全性攻击实例和阻止方法
2020/12/16 PHP
jQuery图片播放8款精美插件分享
2013/02/17 Javascript
jQuery中bind,live,delegate与one方法的用法及区别解析
2013/12/30 Javascript
安装使用Mongoose配合Node.js操作MongoDB的基础教程
2016/03/01 Javascript
jquery 删除节点 添加节点 找兄弟节点的简单实现
2016/12/07 Javascript
利用CSS、JavaScript及Ajax实现图片预加载的三大方法
2017/01/22 Javascript
微信小程序页面缩放式侧滑效果的实现代码
2018/11/15 Javascript
vue-cli配置flexible过程详解
2019/07/04 Javascript
vue v-for直接循环数字实例
2019/11/07 Javascript
Element-ui树形控件el-tree自定义增删改和局部刷新及懒加载操作
2020/08/31 Javascript
[10:34]DOTA2上海特级锦标赛全纪录
2016/03/25 DOTA
python解析json实例方法
2013/11/19 Python
matplotlib 纵坐标轴显示数据值的实例
2018/05/25 Python
python调用接口的4种方式代码实例
2019/11/19 Python
Python三元运算与lambda表达式实例解析
2019/11/30 Python
IronPython连接MySQL的方法步骤
2019/12/27 Python
Python Tricks 使用 pywinrm 远程控制 Windows 主机的方法
2020/07/21 Python
Python如何实现大型数组运算(使用NumPy)
2020/07/24 Python
使用纯HTML5编写一款网页上的时钟的代码分享
2015/11/16 HTML / CSS
html5 input输入实时检测以及延时优化
2018/07/18 HTML / CSS
Paradigit比利时电脑卖场:购买笔记本、电脑、平板和外围设备
2016/11/28 全球购物
互动出版网:专业书籍
2017/03/21 全球购物
英国创新设计文具、卡片和礼品包装网站:Paperchase
2018/07/14 全球购物
世界各地的当地人的食物体验:Eatwith
2019/07/26 全球购物
企业管理专业个人求职信范文
2013/09/24 职场文书
计算机相关的自我评价
2014/01/15 职场文书
优秀求职信范文分享
2014/01/26 职场文书
企业申诉管理制度
2014/01/30 职场文书
幼儿园父亲节活动方案
2014/03/11 职场文书
社区道德讲堂实施方案
2014/03/21 职场文书
2014年自愿离婚协议书范本
2014/09/25 职场文书
2014年流动人口工作总结
2014/11/26 职场文书
银行招聘自荐信
2015/03/06 职场文书
计算机实训心得体会
2016/01/14 职场文书