面向对象实现文件下载系统

Server端代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/python3
# @Time : 2024/8/24 9:46
# @Author : Proton
# @FileName: netdisk_server.py
from socket import *
import struct
import os

class Server:
def __init__(self, ip, port):
self.s_listen:socket = None
self.ip = ip
self.port = port

def tcp_init(self):
self.s_listen = socket(AF_INET, SOCK_STREAM)
self.s_listen.bind((self.ip, self.port))
self.s_listen.listen(128)

def task(self):
new_client, client_addr = self.s_listen.accept()
print(client_addr)
user = User(new_client)
user.deal_command()


class User:
"""
每一个user对象对应一个客户端
"""
def __init__(self, new_client):
self.user: socket = new_client
self.username = None
self.path = os.getcwd() # 存储连上的用户的路径

def train_send(self, content_bytes):
"""
以开火车的形式发送,先发长度,再发内容
:param content:
:return:
"""
content_len_bytes = struct.pack('I', len(content_bytes))
self.user.send(content_len_bytes+content_bytes)

def train_recv(self):
"""
开火车接收,先接收文件名/内容长度,4B,再接收文件名/内容
:return:
"""
train_head_bytes = self.user.recv(4)
train_head_len = struct.unpack('I', train_head_bytes)
# 为什么不decode,因为不一定是文本,也可能是音乐or电影
return self.user.recv(train_head_len[0])

def deal_command(self):
while True:
# 接收命令应该以开火车的形式收
command = self.train_recv().decode('utf8')
if command[:2] == 'ls':
self.do_ls()
elif command[:2] == 'cd':
self.do_cd(command)
elif command[:3] == 'pwd':
self.do_pwd()
elif command[:2] == 'rm':
self.do_rm(command)
elif command[:4] == 'puts':
self.puts_file()
elif command[:4] == 'gets':
self.gets_file(command)
else:
print('wrong command.')

def do_ls(self):
data = ''
cur_list = os.listdir('.')
for i in cur_list:
data += i + ' '*5 + str(os.stat(i).st_size) + '\n'
self.train_send(data.encode('utf8'))

def do_cd(self, command):
path = command.split()[1]
os.chdir(path)
self.path = os.getcwd()
self.train_send(self.path.encode('utf8'))

def do_pwd(self):
self.train_send(self.path.encode('utf8'))

def do_rm(self, command):
"""
深度优先遍历,实现删除非空文件夹
:param command:
:return:
"""
rm_target = command.split()[1]
if os.path.isdir(rm_target) and os.listdir(rm_target): # 若为非空目录
file_list = os.listdir(rm_target) # 继续先删深处的文件
for i in file_list:
self.do_rm(command + '/' + i)
os.rmdir(rm_target) # 最后再删掉当前这个已经空了的目录
elif os.path.isdir(rm_target) and not os.listdir(rm_target): # 空目录
os.rmdir(rm_target)
else: # 普通文件
os.remove(rm_target)

def puts_file(self):
data = self.train_recv()
file = open('f[复件]', mode='wb')
file.write(data)
file.close()

def gets_file(self, command):
file_name = command.split()[1]
my_file = open(file_name, mode='rb') # 字节流形式打开二进制文件
data = my_file.read()
self.train_send(data)
my_file.close()


if __name__ == '__main__':
s = Server('', 2000)
s.tcp_init()
s.task()

面向对象实现文件下载系统
http://paopaotangzu.icu/2024/08/23/4-面向对象实现文件下载系统/
作者
paopaotangzu
发布于
2024年8月23日
许可协议