服务器端代码
1 import socket 2 import os 3 import threading 4 5 6 # 处理客户端请求下载文件的操作(从主线程提出来的代码) 7 def deal_client_request(ip_port, service_client_socket): 8 # 连接成功后,输出“客户端连接成功”和客户端的ip和端口 9 print("客户端连接成功", ip_port) 10 # 接收客户端的请求信息 11 file_name = service_client_socket.recv(1024) 12 # 解码 13 file_name_data = file_name.decode("utf-8") 14 # 判断文件是否存在 15 if os.path.exists(file_name_data): 16 #输出文件字节数 17 fsize = os.path.getsize(file_name_data) 18 #转化为兆单位 19 fmb = fsize/float(1024*1024) 20 #要传输的文件信息 21 senddata = "文件名:%s 文件大小:%.2fMB"%(file_name_data,fmb) 22 #发送和打印文件信息 23 service_client_socket.send(senddata.encode("utf-8")) 24 print("请求文件名:%s 文件大小:%.2f MB"%(file_name_data,fmb)) 25 #接受客户是否需要下载 26 options = service_client_socket.recv(1024) 27 if options.decode("utf-8") == "y": 28 # 打开文件 29 with open(file_name_data, "rb") as f: 30 # 计算总数据包数目 31 nums = fsize/1024 32 # 当前传输的数据包数目 33 cnum = 0 34 35 while True: 36 file_data = f.read(1024) 37 cnum = cnum + 1 38 jindu = cnum/nums*100 39 40 print("当前已下载:%.2f%%"%jindu,end = "\r") 41 if file_data: 42 # 只要读取到数据,就向客户端进行发送 43 service_client_socket.send(file_data) 44 # 数据读完,退出循环 45 else: 46 print("请求的文件数据发送完成") 47 break 48 else: 49 print("下载取消!") 50 else: 51 print("下载的文件不存在!") 52 # 关闭服务当前客户端的套接字 53 service_client_socket.close() 54 55 56 if __name__ == ‘__main__‘: 57 # 把工作目录切换到data目录下 58 os.chdir("./data") 59 # 创建套接字 60 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 61 # 绑定端口号 62 tcp_server_socket.bind(("", 3356)) 63 # 设置监听,将主动套接字变为被动套接字 64 tcp_server_socket.listen(128) 65 66 # 循环调用accept,可以支持多个客户端同时连接,和多个客户端同时下载文件 67 while True: 68 service_client_socket, ip_port = tcp_server_socket.accept() 69 # 连接成功后打印套接字号 70 #print(id(service_client_socket)) 71 72 # 创建子线程 73 sub_thread = threading.Thread(target=deal_client_request, args=(ip_port, service_client_socket)) 74 # 启动子线程 75 sub_thread.start()
客户端代码
1 # 多任务文件下载器客户端 2 import socket 3 4 5 if __name__ == ‘__main__‘: 6 # 创建套接字 7 tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 # 和服务端连接 9 server_ip = input("输入服务器IP:") 10 tcp_client_socket.connect((server_ip, 3356)) 11 # 发送下载文件的请求 12 file_name = input("请输入要下载的文件名:") 13 # 编码 14 file_name_data = file_name.encode("utf-8") 15 # 发送文件下载请求数据 16 tcp_client_socket.send(file_name_data) 17 # 接收要下载的文件信息 18 file_info = tcp_client_socket.recv(1024) 19 # 文件信息解码 20 info_decode = file_info.decode("utf-8") 21 print(info_decode) 22 #获取文件大小 23 fileszie = float(info_decode.split(‘:‘)[2].split(‘MB‘)[0]) 24 fileszie2 = fileszie*1024 25 # 是否下载?输入y 确认 输入q 取消 26 opts = input("是否下载?(y 确认 q 取消)") 27 if opts == ‘q‘: 28 print("下载取消!程序退出") 29 else: 30 print("正在下载 》》》") 31 #向服务器确认正在下载 32 tcp_client_socket.send(b‘y‘) 33 34 # 把数据写入到文件里 35 with open("./" + file_name, "wb") as file: 36 #目前接收到的数据包数目 37 cnum = 0 38 39 while True: 40 # 循环接收文件数据 41 file_data = tcp_client_socket.recv(1024) 42 # 接收到数据 43 if file_data: 44 # 写入数据 45 file.write(file_data) 46 cnum = cnum+1 47 jindu =cnum/fileszie2*100 48 print("当前已下载:%.2f%%"%jindu,end = "\r") 49 # 接收完成 50 else: 51 print("下载结束!") 52 break 53 # 关闭套接字 54 tcp_client_socket.close()
运行窗口
1)客户端
2)服务器端
注意:客户端和服务器端不要运行在idle中,直接终端运行
原文:https://www.cnblogs.com/fighting25/p/10827769.html