因特網客戶端簡介
. 這裏將因特網理解爲用來傳輸數據的地方,數據在服務提供者和服務使用者之間傳輸,在某種情況下被稱爲“生產者-消費者”,服務器就是生產者,提供服務,而客戶端使用服務。
文件傳輸
文件傳輸因特網協議
. 因特網中最常見的就是傳輸文件,許多協議可以用於在因特網上傳輸文件。最流行包括文件傳輸協議(FTP)、UNIX到UNIX複製協議(UUCP)、用於web的超文本傳輸協議(HTTP)。另外還有(UNIX下的)遠程文件複製命令如此rcp(以及更安全、更靈活的scp和rsync)。
HTTP主要用於基於web的文件下載以及訪問web服務,一般客戶端無須登錄就可以訪問服務器上的文件和服務。大部分HTTP 文件傳輸請求都用於獲取網頁(即將網頁文件下載到本地)。
而 scp 和 rsync 需要用戶登錄到服務器主機。在傳輸文件之前必須驗證客戶端的身份,否則不能上傳或下載文件。FTP 與 scp/rsync 相同,它也可以上傳或下載文件,並採用了 UNIX 的多用戶概念,用戶需要輸入有效的用戶名和密碼。但 FTP 也允許匿名登錄。
文件傳輸協議
. FTP主要用於匿名下載公共文件,也可用於兩臺計算機之間傳輸文件。早在web流行之前,FTP就是在因特網上進行文件傳輸以及下載軟件和源代碼的主要手段之一。
前面提過,FTP要求輸入用戶名和密碼才能訪問FTP服務器,但也允許沒有賬號的用戶匿名登錄,不過管理員要先設置FTP服務器允許匿名用戶登錄,但與登錄用戶相比,匿名用戶只能使用有限的幾個FTP命令。
FTP協議的工作流程基本如下:
1.客戶端連接遠程主機上的FTP服務器;
2.客戶端輸入賬號和密碼;
3.客戶端進行文件傳輸或各種信息查詢;
4.客戶端從遠程FTP服務器退出,結束傳輸。
有時由於網絡兩邊計算機的崩潰或是網絡的問題,會導致整個傳輸在完成之前就被中斷。如果客戶端超過15分鐘還沒有響應,FTP連接就會超時並中斷。
在底層,FTP使用的是TCP。可以將FTP看做客戶端/服務器編程中的特殊情況,因爲這裏的服務器和客戶端都使用兩個套接字來通信:一個是控制和命令端口(21端口),一個是數據端口(有時是20端口)。之所以說是“有時”是因爲FTP有兩種模式:主動和被動。只有在主動模式下服務器才使用數據端口。在服務器將20號端口設置爲數據端口後,它“主動”連接客戶端的數據端口;而在被動模式下,服務器只是告訴客戶端一個隨機的數據端口號,客戶端必須主動建立數據連接。
Python與FTP
. Python編寫FTP客戶端程序的流程如下:
1.連接到服務器;
2.登錄;
3.發出服務請求(希望得到響應);
4.退出。
在使用Python的FTP支持時,所需要做的就是導入ftplib模塊,並實例化一個ftplib.FTP類對象,通過該對象來完成FTP的所有操作。
ftplib.FTP類的方法
. 下表中列出了最常用的幾個方法:
方法 | 描述 |
---|---|
login(user=‘anonymous’,passwd=’’,acct=’’) | 登錄FTP服務器,所有參數都是可選的 |
pwd() | 獲取當前工作目錄 |
cwd(path) | 把當前工作目錄設置爲path所示的路徑 |
dir ([path[,…[,cb]]) | 顯示 path 目錄裏的內容,可選的參數 cb 是一個回調函數,會傳遞給 retrlines()方法 |
nlst ([path[,…]) | 與 dir()類似,但返回一個文件名列表,而不是顯示這些文件名 |
retrlines(cmd [, cb]) | 給定FTP 命令(如“RETR filename”),用於下載文本文件。可選的回調函數cb 用於處理文件的每一行 |
retrbinary(cmd,cb[,bs=8192[, ra]]) | 與 retrlines()類似,只是這個指令處理二進制文件。回調函數 cb 用於處理每一塊(塊大小默認爲 8KB)下載的數據 |
storlines(cmd, f) | 給定 FTP 命令(如“STOR filename”),用來上傳文本文件。要給定一個文件對象 f |
storbinary(cmd, f[,bs=8192]) | 與 storlines()類似,只是這個指令處理二進制文件。要給定一個文件對象 f,上傳塊大小 bs 默認爲 8KB |
rename(old, new) | 把遠程文件 old 重命名爲 new |
delete(path) | 刪除位於 path 的遠程文件 |
mkd(directory) | 創建遠程目錄 |
rmd(directory) | 刪除遠程目錄 |
quit() | 關閉連接並退出 |
客戶端FTP程序示例
. 以下代碼用來從ftp服務器下載文件:(PS:書上的FTP服務器地址我反正是連接不上,本想照着網上的步驟自己搭建FTP服務器,結果不知道是系統版本還是什麼問題無法做到,所以用了別人私人的服務器地址,就不寫信息了,只能說正常情況下代碼是可以正常工作的。)
import ftplib
import os
import socket
Host = 'xxx.xxx.xxx.xxx'
Dirn = 'xxx/xxx/'
File = 'xxx'
def main():
try: #連接到服務器
f = ftplib.FTP(Host)
except (socket.error,socket.gaierror) as e:
print('無法連接到 "%s"' % Host)
return
print('成功連接到 "%s"' % Host)
try: #登錄
f.login('xxx','xxx')
except ftplib.error_perm:
print('登錄失敗')
f.quit()
return
print('登錄成功')
#print(f.pwd())
try: #更換工作目錄
f.cwd(Dirn)
except ftplib.error_perm:
print('無法進入"%s"' % Dirn)
f.quit()
return
print('進入"%s"成功' % Dirn)
try: #下載文件
f.retrbinary('RETR %s' % File,open(File,'wb').write)
except ftplib.error_perm:
print('讀取文件失敗')
else:
print('文件下載成功')
f.quit()
if __name__ == '__main__':
main()