socket 網絡編程【實現FTP文件上傳和下載】


有四個基本的具體服務器類:

class socketserver.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)
    這使用Internet TCP協議,它在客戶端和服務器之間提供連續的數據流。如果bind_and_activate為true,構造函數將自動嘗試調用server_bind()和server_activate()。其他參數傳遞到BaseServer基類。

class socketserver.UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)
  這使用數據報,其是可能在運輸中不按順序到達或丟失的信息的離散分組。參數與TCPServer相同。

class socketserver.UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)
class socketserver.UnixDatagramServer(server_address, RequestHandlerClass, bind_and_activate=True)
    這些更常用的類與TCP和UDP類類似,但使用Unix域套接字;它們在非Unix平台上不可用。參數與TCPServer相同。

示例:使用SocketServer網絡服務框架實現FTP文件上傳和下載功能

服務端:

 1 # !/usr/bin/python
 2 # -*- coding:utf-8 -*-
 3 '''
 4 _author_=Captain
 5 '''
 6 import SocketServer
 7 import os
 8 
 9 class Myserver(SocketServer.BaseRequestHandler):
10     def handle(self):
11         base_path="D:\\temp"    #文件保存路徑
12         conn=self.request
13         client_address=self.client_address
14         print "客戶端:"+str(client_address)+"connected..."
15         conn.send("服務端已准備接收...")
16         while True:
17             pre_data1,pre_data2=conn.recv(1024).split('|')
18             if pre_data1=='put':  #如果客戶端是要上傳文件
19                 file_name,file_size=pre_data2.split('-')  #對客戶端傳遞過來的文件名和文件大小兩個值分割開
20                 recv_size=0
21                 file_dir=os.path.join(base_path,file_name)   #生成文件保存的路徑
22                 with open(file_dir,'wb') as f:
23                     Flag = True
24                     while Flag:
25                         if int(file_size)>recv_size:
26                             data = conn.recv(1024)
27                             recv_size += len(data)
28                             f.write(data)
29                         else:
30                             recv_size = 0
31                             Flag = False
32                             conn.send("upload successed")
33 
34             elif pre_data1 == 'get':   #如果客戶端是要下載文件
35                 file_size = os.stat(pre_data2).st_size
36                 file_path,file_name = os.path.split(pre_data2)
37                 conn.send(file_name + '|' + str(file_size))  #將文件名和計算出的文件大小發給客戶端
38                 send_size = 0
39                 with open(pre_data2, 'rb') as f:
40                     Flag = True
41                     while Flag:
42                         if send_size + 1024 > file_size:   #如果文件大小不是1024的倍數,即最后的數據
43                             data = f.read(file_size - send_size)
44                             Flag = False
45                         else:
46                             data = f.read(1024)
47                             send_size += 1024
48                         conn.send(data)
49 
50 
51 if __name__ == '__main__':
52     instance = SocketServer.ThreadingTCPServer(('127.0.0.1',8866), Myserver)  #使用異步多進程
53     instance.serve_forever()
View Code

客戶端:

 1 # !/usr/bin/python
 2 # -*- coding:utf-8 -*-
 3 '''
 4 _author_=Captain
 5 '''
 6 import socket
 7 import sys
 8 import os
 9 
10 ip_port=('127.0.0.1',8866)
11 sk=socket.socket()
12 sk.connect(ip_port)
13 print sk.recv(1024)   #接收服務端提示建立連接的消息
14 while True:
15     cmd,file_dir = raw_input('path:').split()  #對輸入的命令進行分割,如:put c:\xx\11.txt
16     if cmd=='put':
17         file_path, file_name = os.path.split(file_dir)
18         file_size=os.stat(file_dir).st_size    #計算文件大小
19         sk.send(cmd + '|' + file_name + '-' + str(file_size))
20         send_size = 0
21         with open(file_dir,'rb') as f:
22             Flag = True
23             while Flag:
24                 if send_size + 1024 > file_size:
25                     data = f.read(file_size - send_size)
26                     Flag = False
27                 else:
28                     data = f.read(1024)
29                     send_size += 1024
30                 sk.send(data)
31             print sk.recv(1024)  # 接收服務端返回文件上傳成功的消息
32 
33     elif cmd=='get':
34         sk.send(cmd + '|' + file_dir)   #把要下載服務端某個文件的具體路徑發送到服務端
35         file_name,file_size=sk.recv(1024).split('|')   #接收服務端返回的文件名和文件大小
36         file_dir = os.path.join(os.getcwd(), file_name)
37         recv_size = 0
38         with open(file_dir, 'wb') as f:
39             Flag = True
40             while Flag:
41                 if int(file_size) > recv_size:
42                     data = sk.recv(1024)
43                     recv_size += len(data)
44                     f.write(data)
45                 else:
46                     recv_size = 0
47                     Flag = False
48                     print 'download successed,文件已保存到 %s' % file_dir
49     else:
50         print "請輸入put或get命令,確認是上傳還是下載文件"
51 
52 sk.close()
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM