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

网络 通信技术
本篇给大家介绍网络通信Socket模块实现文件传输

 实现的效果如下的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

 

责任编辑:姜华 来源: Python之王
相关推荐

2012-03-19 10:35:51

ibmdw

2017-01-15 17:44:56

node网络通信Socket

2009-10-27 16:52:41

VB.NET文件传输

2019-10-22 08:11:43

Socket网络通信网络协议

2024-04-23 13:36:00

2009-09-07 13:38:03

C# HTTP文件传输HTTP文件传输

2009-01-18 09:28:00

2011-08-24 10:18:56

2023-11-04 09:06:11

2010-07-01 15:55:54

FTP文件传输协议

2017-02-27 20:24:27

Linux文件传输命令

2010-06-28 14:25:16

2009-08-26 14:35:00

用C#实现HTTP协议

2011-03-25 14:20:44

263邮箱超大附件

2019-08-30 13:25:09

WinSCPWindowsLinux

2009-08-24 17:20:13

C#网络通信TCP连接

2020-11-12 08:52:16

Python

2019-04-29 10:26:49

TCP网络协议网络通信

2010-11-09 17:28:27

嗅探嗅探网络TFTP

2013-06-10 16:28:23

点赞
收藏

51CTO技术栈公众号