服务器端:
1 import socket
2 from ms.login import read
3 from ms.login import down
4 from ms.login import up
5
6 buffer=1024 #一次读取内容长度字节
7 sk=socket.socket() #创建socket对象
8 sk.bind(('127.0.0.1',8080)) #绑定地址
9 sk.listen() #监听
10
11 conn,addr=sk.accept() #建立一个连接
12
13 info=conn.recv(50).decode('utf-8') #接收客户端的用户名密码
14 user,psd=info.split('|') #分割获取用户名 和 密码
15
16 ret=read(user,psd) #调read读取用户名信息 验证用户名密码是否正确
17 if ret: #登录成功
18 conn.send(bytes('ok'.encode('utf-8'))) #返回一个OK
19 conn.send(bytes('用户登录成功,请选择要执行的操作【U:上传文件】【D:下载文件】'.encode('utf-8')))
20
21 choice=conn.recv(4).decode('utf-8') #客户端选择上传还是下载
22
23 if choice=='U': #文件上传
24 up(conn,buffer) #调上传方法
25
26 elif choice=='D': # 文件下载
27 down(conn) #调下载方法
28 else:
29 print('error,错误的操作指令!')
30 else: #登录失败 关闭连接和对象
31 conn.send(bytes('用户登录失败,断开连接...'.encode('utf-8')))
32 conn.close()
33 sk.close()
调用函数的模块:
1 import os
2 import struct
3 import operator
4 import time
5 import json
6
7
8 #登录验证
9 def read(user,psd):
10 with open('info','r',encoding='utf-8')as f:
11 for i in f: #读取所有记录
12 i=i.strip() #去空格
13 if user in i: #如果用户名相匹配
14 n_user,n_psd=i.split('|') #分割字符串 得到用户名密码
15 if n_psd==psd:
16 return True #密码正确则为TRUE
17 else:
18 return False #错误则为FALSE
19 #上传
20 def up(conn,buffer):
21 long=conn.recv(4) #4字节的数据长度包
22 pack_long=struct.unpack('i',long)[0] #报头的长度
23 filejson=conn.recv(pack_long).decode('utf-8')
24 fileinfo=json.loads(filejson) #报头内容
25
26 filename = fileinfo['filename']
27 filesize = fileinfo['filesize']
28
29 with open(filename, 'wb')as f: #将接收到的数据写入文件
30 while filesize:
31 if filesize >= buffer: #如果文件大小 大于读取数据量
32 filedata = conn.recv(buffer)
33 f.write(filedata) #就将读取的数据量写入
34 filesize -= buffer
35 else:
36 filedata = conn.recv(filesize)
37 f.write(filedata) #直接把文件写入
38 break
39 print('文件%s上传成功' % filename)
40
41
42 #下载
43 def down(conn):
44 files = os.listdir()
45 lis_file = ''
46 for i in files:
47 lis_file += i + '
'
48 if operator.eq(lis_file, ''): # 如果文件列表为空
49 conn.send(''.encode('utf-8'))
50 else:
51 conn.send(lis_file.encode('utf-8')) #把文件列表发给客户端
52 while True:
53 filename=conn.recv(1024).decode('utf-8') #接收要下载的文件名
54 if filename not in files:
55 conn.send(bytes('文件名不存在!'.encode('utf-8')))
56 else:
57 conn.send(bytes('开始文件传输!'.encode('utf-8')))
58 break
59 size=os.stat(filename).st_size
60 info=struct.pack('i',size)
61 conn.send(info) #文件信息大小打包发送给客户端
62
63 with open(filename,'rb')as f:
64 while True:
65 file_data=f.read(4096)
66 if not file_data:
67 break
68 conn.send(file_data)
69
70 show='{0}
下载文件:{1}:
{2}byte
Successful...
'.format(time.strftime('%Y-%m-%d:%H:%M:%S',time.localtime(time.time())),filename,size)
71 print(show)
72 path=os.path.dirname(os.path.abspath(__file__))
73 path=os.path.join(path,'log')
74
75 os.chdir(path) #临时把当前目录变为 E:programmslog
76 with open('data_log','a',encoding='utf-8')as f:
77 f.write(show) #把输出信息记录入日志
客户端:
1 import socket
2 import struct
3 import os,sys
4 import operator
5 import time
6 import json
7
8 buffer=1024
9
10 sk=socket.socket()
11 sk.connect(('127.0.0.1',8080))
12 user=input('请输入用户名:')
13 psd=input('请输入密码:')
14 login=str(user)+'|'+str(psd)
15 sk.send(bytes(login.encode('utf-8'))) #传用户名密码给客户端
16 ret=sk.recv(1024).decode('utf-8') #接收登录状态 ok
17
18 if ret=='ok':
19 menu=sk.recv(1024).decode('utf-8')
20 print(menu) #显示操作菜单
21 do=input('请输入要执行的操作...').upper()
22 sk.send(bytes(do.encode('utf-8'))) #输入上传还是下载
23
24 #选择上传
25 if do=='U':
26 filepath = input('请输入要上传的文件路径
')
27 filename = input('请输入文件名
')
28
29 path = os.path.join(filepath, filename)
30 filesize = os.stat(path).st_size # 文件大小
31 fileinfo = {'filename': filename, 'filepath': filepath,'filesize':filesize}
32 filejson=json.dumps(fileinfo).encode('utf-8')
33 long=len(filejson) #报头的长度
34 pack_long=struct.pack('i',long) #报头长度变为4字节
35 sk.send(pack_long)
36 sk.send(filejson)
37
38 with open(path, 'rb')as f:
39 while filesize:
40 if filesize >= 1024:
41 filedata = f.read(buffer)
42 sk.send(filedata)
43 filesize -= buffer
44 else:
45 filedata = f.read(filesize)
46 sk.send(filedata)
47 break
48
49 show = '{0}
上传文件:{1}:
{2}byte
Successful...
'.format(
50 time.strftime('%Y-%m-%d:%H:%M:%S', time.localtime(time.time())), filename,filesize)
51 print(show)
52
53
54 # 选择下载
55 elif do=='D':
56 r=sk.recv(1024).decode('utf-8') #收到文件列表
57 if operator.eq(r,''):
58 print('没有可以下载的文件')
59 print(r)
60 filename= input('请输入要下载的文件名>>>')
61 sk.send(bytes(filename.encode('utf-8'))) #发送要下载的文件名
62 state=sk.recv(1024).decode('utf-8') #文件下载状态
63 print(state)
64
65 info=sk.recv(4) #4字节的包
66 size=struct.unpack('i',info)[0] #文件的字节大小
67 print(filename,size)
68
69 data=sk.recv(size).decode('utf-8')
70
71 path = os.path.dirname(os.path.abspath(__file__))
72 path = os.path.join(path, 'down')
73 os.chdir(path)
74 with open(filename,'w+',encoding='utf-8')as f:
75 f.write(data)
76 print(data)
77
78 else:
79 print('error,错误的操作指令!')
80
81
82 sk.close()