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中的RSS处理
Apr 13 Python
浅谈Python 的枚举 Enum
Jun 12 Python
python中urlparse模块介绍与使用示例
Nov 19 Python
pandas数据预处理之dataframe的groupby操作方法
Apr 13 Python
Python3enumrate和range对比及示例详解
Jul 13 Python
python 画出使用分类器得到的决策边界
Aug 21 Python
解决Pytorch训练过程中loss不下降的问题
Jan 02 Python
Pytorch 实现focal_loss 多类别和二分类示例
Jan 14 Python
使用Python3 poplib模块删除服务器多天前的邮件实现代码
Apr 24 Python
详解Django中views数据查询使用locals()函数进行优化
Aug 24 Python
python 录制系统声音的示例
Dec 21 Python
用Python自动清理系统垃圾的实现
Jan 18 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实现时间比较和时间差计算的方法示例
2017/07/24 PHP
php成功操作redis cluster集群的实例教程
2019/01/13 PHP
用JavaScript编写COM组件的步骤
2009/03/17 Javascript
EasySlider 基于jQuery功能强大简单易用的滑动门插件
2010/06/11 Javascript
jQuery实现ichat在线客服插件
2014/12/29 Javascript
JS实现点击按钮后框架内载入不同网页的方法
2015/05/05 Javascript
jQuery实现Email邮箱地址自动补全功能代码
2015/11/03 Javascript
JS使用post提交的两种方式
2015/12/03 Javascript
利用jQuery实现WordPress中@的ID悬浮显示评论内容
2015/12/11 Javascript
极易被忽视的javascript面试题七问七答
2016/02/15 Javascript
Bootstrap导航条可点击和鼠标悬停显示下拉菜单的实现代码
2016/06/23 Javascript
AngularJS 控制器 controller的详解
2017/10/17 Javascript
浅谈如何通过node.js对数据进行MD5加密
2018/05/16 Javascript
vue组件之间的数据传递方法详解
2019/04/19 Javascript
vue实现配置全局访问路径头(axios)
2019/11/01 Javascript
[41:17]VG vs Optic 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
用Python和MD5实现网站挂马检测程序
2014/03/13 Python
使用Python从有道词典网页获取单词翻译
2016/07/03 Python
Python正则表达式匹配日期与时间的方法
2019/07/07 Python
Django 外键的使用方法详解
2019/07/19 Python
Python实现滑动平均(Moving Average)的例子
2019/08/24 Python
python3.7将代码打包成exe程序并添加图标的方法
2019/10/11 Python
python GUI库图形界面开发之PyQt5浏览器控件QWebEngineView详细使用方法
2020/02/26 Python
Django模型中字段属性choice使用说明
2020/03/30 Python
Scrapy实现模拟登录的示例代码
2021/02/21 Python
域名注册、建站工具、网页主机、SSL证书:Dynadot
2017/01/06 全球购物
德国大型和小型家用电器网上商店:Energeto
2019/05/15 全球购物
项目投资建议书
2014/05/16 职场文书
地理信息科学专业推荐信
2014/09/08 职场文书
合作经营协议书范本
2014/09/16 职场文书
2014市府办领导班子“四风问题”对照检查材料思想汇报
2014/09/24 职场文书
个人对照检查材料思想汇报(四风问题)
2014/09/25 职场文书
2014年帮扶工作总结
2014/11/26 职场文书
2016小学教师读书心得体会
2016/01/13 职场文书
numpy数据类型dtype转换实现
2021/04/24 Python
MySQL中datetime时间字段的四舍五入操作
2021/10/05 MySQL