当前位置:主页 > 查看内容

网络通信Socket模块实现文件传输

发布时间:2021-06-16 00:00| 位朋友查看

简介:实现的效果如下的Gif所示,就是网络通信Socket模块实现文件下载传输。 服务端 首先需要获取本机ip,这里服务端采用多线程的方法,就是定义一个函数,然后用threading创建任务。客户端连接成功,接收客户端的请求信息,就是下载的文件名。所以需要判断,有输……

实现的效果如下的Gif所示,就是网络通信Socket模块实现文件下载传输。

服务

首先需要获取本机ip,这里服务端采用多线程的方法,就是定义一个函数,然后用threading创建任务。客户端连接成功,接收客户端的请求信息,就是下载的文件名。所以需要判断,有输出文件字节数。然后在问用户是不是要下载,得到信息就使用 while True: 读文件的内容,再一个send。看代码是不是就是这么回事。

  1. import socket 
  2. import os 
  3. import threading 
  4.  
  5. # 获取本机ip 
  6. def get_host_ip(): 
  7.     try: 
  8.         s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
  9.         s.connect(('8.8.8.8', 80)) 
  10.         ip = s.getsockname()[0] 
  11.     finally: 
  12.         s.close() 
  13.  
  14.     return ip 
  15.  
  16. # 处理客户端请求下载文件的操作(从主线程提出来的代码) 
  17. def deal_client_request(ip_port, service_client_socket): 
  18.     # 连接成功后,输出“客户端连接成功”和客户端的ip和端口 
  19.     print("客户端连接成功", ip_port) 
  20.     # 接收客户端的请求信息【recv】 
  21.     file_name = service_client_socket.recv(1024) 
  22.     # 解码 
  23.     file_name_data = file_name.decode("utf-8"
  24.     # 判断文件是否存在 
  25.     if os.path.exists(file_name_data): 
  26.         #输出文件字节数 
  27.         fsize = os.path.getsize(file_name_data) 
  28.         #转化为兆单位 
  29.         fmb = fsize/float(1024*1024) 
  30.         #要传输的文件信息 
  31.         senddata = "文件名:%s  文件大小:%.2fMB"%(file_name_data,fmb) 
  32.         #发送和打印文件信息【send】 
  33.         service_client_socket.send(senddata.encode("utf-8")) 
  34.         print("请求文件名:%s  文件大小:%.2f MB"%(file_name_data,fmb)) 
  35.         #接受客户是否需要下载【recv】 
  36.         options = service_client_socket.recv(1024) 
  37.         if options.decode("utf-8") == "y"
  38.             # 打开文件 
  39.             with open(file_name_data, "rb"as f: 
  40.                 # 计算总数据包数目 
  41.                 nums = fsize/1024 
  42.                 # 当前传输的数据包数目 
  43.                 cnum = 0 
  44.  
  45.                 while True
  46.                     file_data = f.read(1024) 
  47.                     cnum = cnum + 1 
  48.                     #progress = cnum/nums*100 
  49.  
  50.                     #print("当前已下载:%.2f%%"%progress,end = "\r"
  51.                     if file_data: 
  52.                         # 只要读取到数据,就向客户端进行发送【send】 
  53.                         service_client_socket.send(file_data) 
  54.                     # 数据读完,退出循环 
  55.                     else
  56.                         print("请求的文件数据发送完成"
  57.                         break 
  58.         else
  59.             print("下载取消!"
  60.     else
  61.         print("下载的文件不存在!"
  62.     # 关闭服务当前客户端的套接字【close】 
  63.     service_client_socket.close() 
  64.  
  65.  
  66. if __name__ == '__main__'
  67.     # 获取本机ip 
  68.     print("TCP文件传输服务器,本机IP:" + get_host_ip()) 
  69.      
  70.     # 把工作目录切换到data目录下 
  71.     os.chdir("./data"
  72.     # 创建套接字【socket】 
  73.     tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
  74.     # 绑定端口号【bind】 
  75.     tcp_server_socket.bind(("", 3356)) 
  76.     # 设置监听,将主动套接字变为被动套接字【listen】 
  77.     tcp_server_socket.listen(128) 
  78.  
  79.     # 循环调用【accept】,可以支持多个客户端同时连接,和多个客户端同时下载文件 
  80.     while True
  81.         service_client_socket, ip_port = tcp_server_socket.accept() 
  82.         # 连接成功后打印套接字号 
  83.         #print(id(service_client_socket)) 
  84.  
  85.         # 创建子线程 
  86.         sub_thread = threading.Thread(target=deal_client_request, args=(ip_port, service_client_socket)) 
  87.         # 启动子线程 
  88.         sub_thread.start() 

客户端

客户端更简单,连接服务端,发送下载文件的请求,定义一个写入的文件夹,就是小儿科东西。不写了,看代码。

  1. # -*- coding:utf-8 -*- 
  2. # 多任务文件下载器客户端 
  3. import socket 
  4. import os 
  5.  
  6. if __name__ == '__main__'
  7.     # 创建套接字【socket】 
  8.     tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
  9.     # 和服务端连接【connect】 
  10.     server_ip = input("输入服务器IP:"
  11.     tcp_client_socket.connect((server_ip, 3356)) 
  12.     # 发送下载文件的请求 
  13.     file_name = input("请输入要下载的文件名:"
  14.     # 编码 
  15.     file_name_data = file_name.encode("utf-8"
  16.     # 发送文件下载请求数据【send】 
  17.     tcp_client_socket.send(file_name_data) 
  18.     # 接收要下载的文件信息【recv】 
  19.     file_info = tcp_client_socket.recv(1024) 
  20.     # 文件信息解码 
  21.     info_decode = file_info.decode("utf-8"
  22.     print(info_decode) 
  23.     #获取文件大小 
  24.     fileszie = float(info_decode.split(':')[2].split('MB')[0]) 
  25.     fileszie2 = fileszie*1024 
  26.     # 是否下载?输入y 确认 输入q 取消 
  27.     opts = input("是否下载?(y 确认 q 取消)"
  28.     if opts == 'q'
  29.         print("下载取消!程序退出"
  30.     else
  31.         print("正在下载 >>>>>>"
  32.         #向服务器确认正在下载【send】 
  33.         tcp_client_socket.send(b'y'
  34.  
  35.         recvpath = "./receive/" 
  36.         if not os.path.exists(recvpath): 
  37.             os.mkdir(recvpath)  
  38.          
  39.         # 把数据写入到文件里 
  40.         with open(recvpath + file_name, "wb"as file: 
  41.             #目前接收到的数据包数目 
  42.             cnum = 0 
  43.  
  44.             while True
  45.                 # 循环接收文件数据【recv】 
  46.                 file_data = tcp_client_socket.recv(1024) 
  47.                 # 接收到数据 
  48.                 if file_data: 
  49.                     # 写入数据 
  50.                     file.write(file_data) 
  51.                     cnum = cnum+1 
  52.                     #progress =cnum/fileszie2*100 
  53.                     #print("当前已下载:%.2f%%"%progress,end = "\r"
  54.                 # 接收完成 
  55.                 else
  56.                     print("下载结束!"
  57.                     break 
  58.     # 关闭套接字【close】 
  59.     tcp_client_socket.close() 

扩展

如果手机想要下载电脑上的文件(电脑和手机之间),需要确保电脑和手机连接的网络在同一个路由器下

通过ipconfig查看ip

命令行输入python -m http.server 8888来搭建局域网

手机访问192.168.0.101:8888即可下载文件

本文已收录 GitHub,传送门~[1] ,里面更有大厂面试完整考点,欢迎 Star。

Reference

[1]传送门~:

https://github.com/MaoliRUNsen/runsenlearnpy100


本文转载自网络,原文链接:https://mp.weixin.qq.com/s/2eiBfrglbpp9ZDZTWPRIYg
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文

  • 周排行
  • 月排行
  • 总排行

随机推荐