TCP简单实现文件上传与下载

服务器端:

 1 import socket
 2 from ms.login import read
 3 import os
 4 import sys
 5 import struct
 6 import operator
 7 import time
 8 from ms.login import down
 9 from ms.login import up
10 
11 sk=socket.socket()   #创建socket对象
12 sk.bind(('127.0.0.1',8080))  #绑定地址
13 sk.listen()  #监听
14 
15 conn,addr=sk.accept() #建立一个连接
16 
17 info=conn.recv(50).decode('utf-8')   #接收客户端的用户名密码
18 user,psd=info.split('|')   #分割获取用户名 和 密码
19 
20 ret=read(user,psd)  #调read读取用户名信息 验证用户名密码是否正确
21 if ret:  #登录成功
22     conn.send(bytes('ok'.encode('utf-8')))   #返回一个OK
23     conn.send(bytes('用户登录成功,请选择要执行的操作【U:上传文件】【D:下载文件】'.encode('utf-8')))
24 
25     choice=conn.recv(4).decode('utf-8')   #客户端选择上传还是下载
26 
27     if choice=='U':  #文件上传
28         up(conn)    #调上传方法
29 
30     elif choice=='D':   # 文件下载
31         down(conn)  #调下载方法
32     else:
33         print('error,错误的操作指令!')
34 else:   #登录失败 关闭连接和对象
35     conn.send(bytes('用户登录失败,断开连接...'.encode('utf-8')))
36     conn.close()
37     sk.close()

调用函数的模块:

 1 import os
 2 import sys
 3 import struct
 4 import operator
 5 import time
 6 import socket
 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):
21     long=conn.recv(4)   #4字节的数据长度包
22     size=struct.unpack('i',long)[0]
23 
24     ret=conn.recv(size).decode('utf-8')  #来自客户端发过来的数据
25     print(ret)
26 
27     path = os.path.dirname(os.path.abspath(__file__))
28     path = os.path.join(path, 'up')
29 
30     os.chdir(path)
31     filename = conn.recv(50).decode('utf-8')
32 
33     with open(filename,'w+',encoding='utf-8')as f:
34         f.write(ret)
35 
36 
37 #下载
38 def down(conn):
39     files = os.listdir()
40     lis_file = ''
41     for i in files:
42         lis_file += i + '\n'
43     if operator.eq(lis_file, ''):  # 如果文件列表为空
44         conn.send(''.encode('utf-8'))
45     else:
46         conn.send(lis_file.encode('utf-8'))  #把文件列表发给客户端
47         while True:
48             filename=conn.recv(1024).decode('utf-8')  #接收要下载的文件名
49             if filename not in files:
50                 conn.send(bytes('文件名不存在!'.encode('utf-8')))
51             else:
52                 conn.send(bytes('开始文件传输!'.encode('utf-8')))
53                 break
54         size=os.stat(filename).st_size
55         info=struct.pack('i',size)
56         conn.send(info)    #文件信息大小打包发送给客户端
57 
58         with open(filename,'rb')as f:
59             while True:
60                 file_data=f.read(4096)
61                 if not file_data:
62                     break
63                 conn.send(file_data)
64 
65         show='{0}\n下载文件:{1}:\n{2}byte\nSuccessful...\n\n'.format(time.strftime('%Y-%m-%d:%H:%M:%S',time.localtime(time.time())),filename,size)
66         print(show)
67         path=os.path.dirname(os.path.abspath(__file__))
68         path=os.path.join(path,'log')
69 
70         os.chdir(path)    #临时把当前目录变为 E:\program\ms\log
71         with open('data_log','a',encoding='utf-8')as f:
72             f.write(show)              #把输出信息记录入日志

客户端:

 1 import socket
 2 import struct
 3 import os,sys
 4 import operator
 5 import time
 6 
 7 sk=socket.socket()
 8 sk.connect(('127.0.0.1',8080))
 9 user=input('请输入用户名:')
10 psd=input('请输入密码:')
11 login=str(user)+'|'+str(psd)
12 sk.send(bytes(login.encode('utf-8')))  #传用户名密码给客户端
13 ret=sk.recv(1024).decode('utf-8')   #接收登录状态  ok
14 
15 if ret=='ok':
16     menu=sk.recv(1024).decode('utf-8')
17     print(menu)              #显示操作菜单
18     do=input('请输入要执行的操作...').upper()
19     sk.send(bytes(do.encode('utf-8')))    #输入上传还是下载
20 
21     #选择上传
22     if do=='U':
23         path = input('请输入要上传的文件路径\n')
24         filename = input('请输入文件名\n')
25         size=struct.pack('i',os.stat(filename).st_size)
26         sk.send(size)     #发送要上传文件的大小
27         long=os.stat(filename).st_size
28 
29         with open(path,'rb')as f:
30             while True:
31                 file_data=f.read(4096)
32                 if not file_data:
33                     break
34                 sk.send(file_data)    #把要上传的数据传给服务器
35 
36         show = '{0}\n上传文件:{1}:\n{2}byte\nSuccessful...\n\n'.format(
37             time.strftime('%Y-%m-%d:%H:%M:%S', time.localtime(time.time())), filename,long)
38         print(show)
39         sk.send(bytes(filename.encode('utf-8')))
40 
41 
42     # 选择下载
43     elif do=='D':
44         r=sk.recv(1024).decode('utf-8')   #收到文件列表
45         if operator.eq(r,''):
46             print('没有可以下载的文件')
47         print(r)
48         filename= input('请输入要下载的文件名>>>')
49         sk.send(bytes(filename.encode('utf-8')))   #发送要下载的文件名
50         state=sk.recv(1024).decode('utf-8')  #文件下载状态
51         print(state)
52 
53         info=sk.recv(4)   #4字节的包
54         size=struct.unpack('i',info)[0]  #文件的字节大小
55         print(filename,size)
56 
57         data=sk.recv(size).decode('utf-8')
58 
59         path = os.path.dirname(os.path.abspath(__file__))
60         path = os.path.join(path, 'down')
61         os.chdir(path)
62         with open(filename,'w+',encoding='utf-8')as f:
63             f.write(data)
64         print(data)
65 
66     else:
67         print('error,错误的操作指令!')
68 
69 
70 sk.close()

猜你喜欢

转载自www.cnblogs.com/wen-kang/p/9399223.html