1. 程式人生 > >TCP簡單實現文件上傳與下載

TCP簡單實現文件上傳與下載

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簡單實現文件上傳與下載