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天气预报采集器实现代码(网页爬虫)
Oct 07 Python
跟老齐学Python之总结参数的传递
Oct 10 Python
Python os模块介绍
Nov 30 Python
python递归计算N!的方法
May 05 Python
浅谈插入排序算法在Python程序中的实现及简单改进
May 04 Python
Python编程实现正则删除命令功能
Aug 30 Python
关于Tensorflow中的tf.train.batch函数的使用
Apr 24 Python
深入浅析Python获取对象信息的函数type()、isinstance()、dir()
Sep 17 Python
python PIL/cv2/base64相互转换实例
Jan 09 Python
python中resample函数实现重采样和降采样代码
Feb 25 Python
用python写PDF转换器的实现
Oct 29 Python
如何基于Python爬虫爬取美团酒店信息
Nov 03 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.MVC的模板标签系统(三)
2006/09/05 PHP
php一句话cmdshell新型 (非一句话木马)
2009/04/18 PHP
Nginx下配置codeigniter框架方法
2015/04/07 PHP
php采集神器cURL使用方法详解
2016/02/19 PHP
PHP与Java对比学习日期时间函数
2016/07/03 PHP
Document 对象的常用方法
2009/07/31 Javascript
开发中可能会用到的jQuery小技巧
2014/03/07 Javascript
20分钟成功编写bootstrap响应式页面 就这么简单
2016/05/12 Javascript
BootStrap 模态框实现刷新网页并关闭功能
2017/01/04 Javascript
详解在Vue中通过自定义指令获取dom元素
2017/03/04 Javascript
详解nodejs微信公众号开发——3.封装消息响应模块
2017/04/10 NodeJs
VUE元素的隐藏和显示(v-show指令)
2017/06/23 Javascript
基于Vue实现后台系统权限控制的示例代码
2017/08/29 Javascript
如何解决.vue文件url引用文件的问题
2019/01/18 Javascript
简单了解JavaScript sort方法
2019/11/25 Javascript
Element-UI+Vue模式使用总结
2020/01/02 Javascript
node运行js获得输出的三种方式示例详解
2020/07/02 Javascript
vue 实现根据data中的属性值来设置不同的样式
2020/08/04 Javascript
简单分析Python中用fork()函数生成的子进程
2015/05/04 Python
Python3.2模拟实现webqq登录
2016/02/15 Python
python 计算文件的md5值实例
2017/01/13 Python
Django 实现admin后台显示图片缩略图的例子
2019/07/28 Python
python 直接赋值和copy的区别详解
2019/08/07 Python
Python socket 套接字实现通信详解
2019/08/27 Python
Python requests模块安装及使用教程图解
2020/06/30 Python
PyCharm 2020.2.2 x64 下载并安装的详细教程
2020/10/15 Python
用CSS3实现Win8风格的方格导航菜单效果
2013/04/10 HTML / CSS
美国蔬菜和植物种子公司:Burpee
2017/02/01 全球购物
美国购买体育、音乐会和剧院门票网站:SelectATicket
2019/09/08 全球购物
2014年教师节国旗下讲话稿
2014/09/10 职场文书
入党政审材料范文
2014/12/24 职场文书
2015年度村委会工作总结
2015/04/29 职场文书
消费者理赔投诉书
2015/07/02 职场文书
二胎满月酒致辞
2015/07/29 职场文书
详细总结Python常见的安全问题
2021/05/21 Python
CentOS安装Nginx并部署vue
2022/04/12 Servers