TCP簡單實現文件上傳與下載
阿新 • • 發佈:2018-08-01
t對象 sys 文件上傳與下載 顯示 close 一個 去空格 ont 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()
TCP簡單實現文件上傳與下載