1. 程式人生 > >Python:socket實現ftp程序

Python:socket實現ftp程序

handler 拋出異常 失敗 all accept ESS net isp spa

剛開始學習socket編程,還不是特熟練,碼了好長時間,中間遇到許多問題,記錄一下用socketserver寫ftp

server端:

 1 #!/usr/bin/env python
 2 
 3 import socketserver,os
 4 
 5 class FTP(socketserver.BaseRequestHandler):
 6     def handle(self):
 7         def clientsend(filename):
 8             f = open(/ftp/%s %filename,w)
 9         #    while 1:    
10 data = self.request.recv(4096).decode("utf-8") 11 # if not data:break 12 f.write(data) 13 f.close() 14 print(File %s receive done! % filename) 15 def clientdownload(filename): 16 f = open(/ftp/%s %filename,r) 17 data = f.read()
18 f.close() 19 self.request.sendall(data.encode("utf-8")) 20 print(listening connect from:,self.client_address) 21 listmsg = list:\n1.help\t\t\tdispaly the list\n2.send file\t\tsend + filename\n3.download file\t\tdownload + filename\n4.ls\t\t\tShow files and permissions\n5.exit\n
22 self.request.sendall("Welcome my ftp,input \033[34;1m‘help‘\033[0m dispaly meun".encode("utf-8")) 23 while 1: 24 try: 25 re_msg = self.request.recv(1024).decode("utf-8") 26 if not re_msg:break 27 if re_msg == help or re_msg == ?: 28 self.request.sendall(listmsg.encode("utf-8")) 29 elif re_msg.split()[0] == send: 30 filename = re_msg.split()[1] 31 clientsend(filename) 32 elif re_msg.split()[0] == ls: 33 ls_list = os.popen(ls -l /ftp).read().encode("utf-8") 34 self.request.sendall(ls_list) 35 elif re_msg.split()[0] == download: 36 filename = re_msg.split()[1] 37 clientdownload(filename) 38 else: 39 self.request.sendall(Invalid value.encode("utf-8")) 40 finally: 41 pass 42 if __name__ == __main__: #只有程序執行時才會觸發下面的語句,程序被導入調用時,下面的語句不會觸發 43 host = 192.168.101.128 44 port = 2222 45 server = socketserver.ThreadingTCPServer((host,port),FTP) 46 server.serve_forever()

client端:

 1 #!/usr/bin/env python
 2 import socket,sys
 3 
 4 host = 192.168.101.128
 5 port = 2222
 6 
 7 s = socket.socket()
 8 s.connect((host,port))
 9 info = s.recv(8096).decode("utf-8")
10 print(info)
11 while 1:
12     INPUT = str(input(input:))
13     if INPUT.split()[0] == send:
14         s.send(INPUT.encode("utf-8"))
15         filename = INPUT.split()[1]
16         f = open(filename,r)
17         file_data = f.read()
18         f.close()
19         s.sendall(file_data.encode("utf-8"))
20         print(file sent finished!)
21     elif INPUT.split()[0] == download:
22         s.send(INPUT.encode("utf-8"))
23         filename = INPUT.split()[1]
24         f = open(filename,w)
25         data = s.recv(8096).decode("utf-8")
26         f.write(data)
27         f.close()
28         print(%s has been download! %filename)
29     elif INPUT.split()[0] == exit:
30         sys.exit()
31     else:
32         s.send(INPUT.encode("utf-8"))
33         data = s.recv(8096).decode("utf-8")
34         print(data)
35 s.close()

socket 僅支持單線程,socketserver 支持多線程

socketserver:

定義請求處理類時,需要繼承socketserver.BaseRequestHandler,並且需要創建新的handle()函數來處理請求

python中的socketserver模塊已經為我們初始化好了,直接調用即可

self.request.recv(bufsize).decode("utf-8")  讀取請求數據

self.request.sendall().encode("utf-8")    發送數據

self.client_address            客戶端請求的地址

server = socketserver.ThreadingTCPServer((Host,Port),FTP)  多線程!!!

server = socketserver.TCPServer((Host,Port),FTP)        單線程

server.serve_forever()           持續監聽,服務端一直運行,知道收到shutdown信號

socket:

socket.AF_UNIX      只能用於單一的Unix系統進程通信

socket.AF_INET      服務器之間網絡通信

socket.AF_INET6      IPv6

socket.SOCK_STREAM   流式socket,for TCP

socket.SOCK_DGRAM   數據報式socket,for UDP

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.bind((Host,Port))

s.listen()

s.connect((Host,Port))

conn,address = s.accept()  conn是新的套接字對象,可以用來接受和發送數據,address是客戶端的地址

s.close()

s.recv(bufsize)       接受套接字的數據,數據以字符串的形式返回,bufsize是接收的最大數據量

s.sendall(string)       嘗試發送所有數據,成功返回None,失敗則拋出異常

s.getpeername()      返回連接套接字的遠程地址,返回值通常為元組

s.gettimeout()        返回當前超時值,單位為秒,如果沒有設置超時,則為None

Python:socket實現ftp程序