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的Twisted框架编写简单的网络客户端
Apr 16 Python
Python使用Supervisor来管理进程的方法
May 28 Python
Python整型运算之布尔型、标准整型、长整型操作示例
Jul 21 Python
Python数据结构与算法之使用队列解决小猫钓鱼问题
Dec 14 Python
用TensorFlow实现多类支持向量机的示例代码
Apr 28 Python
Python实现 PS 图像调整中的亮度调整
Jun 28 Python
python lambda表达式在sort函数中的使用详解
Aug 28 Python
python数据库编程 Mysql实现通讯录
Mar 27 Python
解决django FileFIELD的编码问题
Mar 30 Python
python matplotlib.pyplot.plot()参数用法
Apr 14 Python
Python爬虫爬取微信朋友圈
Aug 06 Python
python实现逻辑回归的示例
Oct 09 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
一个简单的自动发送邮件系统(一)
2006/10/09 PHP
Windows PHP5和Apache的安装与配置
2009/06/08 PHP
thinkPHP框架实现图像裁剪、缩放、加水印的方法
2017/03/14 PHP
PHP基于IMAP收取邮件的方法示例
2017/08/07 PHP
PHP简单实现二维数组赋值与遍历功能示例
2017/10/19 PHP
JavaScript中获取元素索引的函数
2010/09/10 Javascript
学习面向对象之面向对象的术语
2010/11/30 Javascript
js控制frameSet示例
2013/09/10 Javascript
JavaScript中Math对象方法使用概述
2014/01/02 Javascript
NodeJS Express框架中处理404页面一个方式
2014/05/28 NodeJs
Jquery动态添加及删除页面节点元素示例代码
2014/06/16 Javascript
js实现网页标题栏闪烁提示效果实例分析
2014/11/20 Javascript
js的[defer]和[async]属性
2014/11/24 Javascript
node.js中使用socket.io制作命名空间
2014/12/15 Javascript
使用jquery插件qrcode生成二维码
2015/10/22 Javascript
javascript实现可键盘控制的抽奖系统
2016/03/10 Javascript
JavaScript sort数组排序方法和自我实现排序方法小结
2016/06/06 Javascript
jQuery处理XML文件的几种方法
2016/06/14 Javascript
利用Angularjs和bootstrap实现购物车功能
2016/08/31 Javascript
Easyui使用Dialog行内按钮布局的实例
2017/07/27 Javascript
JS中数组与对象的遍历方法实例小结
2018/08/14 Javascript
vue将毫秒数转化为正常日期格式的实例
2018/09/16 Javascript
JS co 函数库的含义和用法实例总结
2020/04/08 Javascript
JS typeof fn === 'function' && fn()详解
2020/08/22 Javascript
js实现移动端图片滑块验证功能
2020/09/29 Javascript
[01:55]2014DOTA2国际邀请赛快报:国土生病 紧急去医院治疗
2014/07/10 DOTA
[02:53]2018年度DOTA2最佳战队-完美盛典
2018/12/17 DOTA
Python批量转换文件编码格式
2015/05/17 Python
Python操作MySQL模拟银行转账
2018/03/12 Python
python opencv捕获摄像头并显示内容的实现
2019/07/11 Python
python退出循环的方法
2020/06/18 Python
10款最佳Python开发工具推荐,每一款都是神器
2020/10/15 Python
美国在线咖啡、茶和餐厅供应商:LollicupStore
2018/05/04 全球购物
如何判断计算机可能已经中马
2013/03/22 面试题
个人售房合同协议书
2016/03/21 职场文书
电子表的操作介绍说明书
2019/10/28 职场文书