python网络编程证书_《Python网络编程基础》笔记
python網絡編程基礎
==================
Author: lujun9972
Date: 2013-03-08 22:29:20 CST
Table of Contents
=================
1 客戶端與服務器端
1.1 使用inetd或xinetd
1.2 在python中使用syslog
2 域名系統
2.1 正向查找
2.2 反向查找
2.3 獲得運行程序機器的域名信息
2.4 使用pyDNS
3 高級網絡操作
3.1 半開發socket
3.2 超時
3.3 廣播數據
3.4 使用poll()或select()實現事件通知
3.5 urllib2
4 解析HTML和XHTML
4.1 使用HTMLParser模塊解析HTML
4.2 XML和XML-RPC
4.2.1 DOM模型
4.2.2 xmlrpclib庫
5 E-mail服務
5.1 E-mail的編寫和編碼
5.2 SMTP
5.3 POP協議
5.4 IMAP協議
6 FTP
7 數據庫
8 SSL
9 SocketServer
10 SimpleXMLRPCServer
1 客戶端與服務器端
~~~~~~~~~~~~~~~~~~~
1. socket().makefile(操作文件模式,是否開啟緩存模式)方法能夠使得socket變得像file一樣讀寫
緩存一般用在磁盤文件中,在socket環境中,一般不開啟緩存,將該值設為0
2. socket.getservbyname(協議名,udp/tcp)?? 查詢服務端口
3. socket().getsockname()?? /socket().getpeername()??? #獲取地址與端口信息
4. socket異常:
異常????????????? 說明
-----------------+------------------------------------------------
socket.error????? 與一般IO和通訊問題有關
-----------------+------------------------------------------------
socket.gaierror?? 與查詢地址信息有關的
-----------------+------------------------------------------------
socket.herror???? 與其他地址錯誤有關
-----------------+------------------------------------------------
socket.timeout??? 與在一個socket上調用settimeout后,處理超時有關
5. 對于很多操作系統來說,有時候在網絡上發送數據的調用會在遠程服務器確保已經收到信息之前返回。因此很有可能一個來自對sendall成功調用的數據,事實上并沒有被成功收到
為了解決這個問題,一旦結束寫操作,你就應該立刻調用shutdown函數,這樣就會強制清除緩存里面的內容內容,同時如果有任何問題就會產生一個異常
請牢記,數據只有在調用了shutdown函數后才能確保被發送
需要注意的是,makefile()返回的對象并不提供一個對shutdown()的調用,股必須保持原始的socket對象并使用它
6. setsockopt(level,optname,value)
getsockopt(level,optname[,buflen])
level定義了哪個選項將被使用。通常情況下是SOL_SOCKET
選項????????????? 意義???????????????????????????????????????????????????????????????????????????????????????????????????????????????? 期望值
-----------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------
SO_BINDTODEVICE?? 可以使socket只在某個特殊網卡有效???????????????????????????????????????????????????????????????????????????????????? 一個字符串給出設備的名稱或者一個空字符返回默認值
-----------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------
SO_BROADCAST????? 允許廣播地址發送和接受信息,只對UDP有效????????????????????????????????????????????????????????????????????????????? 布爾型
-----------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------
SO_DONTROUTE????? 禁止通過路由器和網關往外發送數據包?????????????????????????????????????????????????????????????????????????????????? 布爾型
-----------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------
SO_KEEPALIVE????? 可以使TCP通信的信息包保持連續性,這些信息包可以在沒有信息傳輸時,使通信的雙方確定連接時保持的??????????????????????? 布爾型
-----------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------
SO_OOBINLINE????? 可以把收到的不正常數據看成是正常的數據;也就是說,會通過一個標準的對recv的調用來接受這些數據???????????????????????? 布爾型
-----------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------
SO_REUSEADDR????? 當socket關閉后,本地端用于該socket的端口號立刻就可以被系統重用,通常來說,只有經過系統定義的一段時間后,才能被重用?? 布爾型
-----------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------
SO_TYPE?????????? 重新得到socket類型(例如SOCK_STREAM或SOCK_DGRAM).只用于getsockopt()?????????????????????????????????????????????????? 整數
1.1 使用inetd或xinetd
======================
inetd和xinetd使用stdin和stdout傳統socket給服務進程
1. xinetd的服務選項說明
選項名稱????? 描述
-------------+----------------------------------------------------------------------------------------------------------------------------------------
flags???????? 各種xinetd特有的flags控制著服務器運轉
如果你只指定NAMEINARGS,那么它就使參數和inetd一樣傳遞
-------------+----------------------------------------------------------------------------------------------------------------------------------------
type????????? 如果你正定義已給不在/etc/services列表上的服務,你就應該使用UNLISTED,否則你可以省略type這一行
-------------+----------------------------------------------------------------------------------------------------------------------------------------
port????????? 如果你設置了type=UNLISTED,則必須在這指定端口號
-------------+----------------------------------------------------------------------------------------------------------------------------------------
socket_type?? 如果是TCP,則為stream。如果是UDP,則是dgram
-------------+----------------------------------------------------------------------------------------------------------------------------------------
protocol????? tcp/udp
-------------+----------------------------------------------------------------------------------------------------------------------------------------
wait????????? 對應所有的TCP服務器,設為no。
對于UDP,如果服務器連接遠程機器并未不同機器的信息包請求一個新的進程來處理,那么也應該使用no
如果UDP在它的端口上處理所有的信息包,知道它被終止,那么應該使用yes
-------------+----------------------------------------------------------------------------------------------------------------------------------------
user????????? 指定了程序應該在哪個用戶下運行
-------------+----------------------------------------------------------------------------------------------------------------------------------------
server??????? 實現服務器實際程序的完整路徑
-------------+----------------------------------------------------------------------------------------------------------------------------------------
server_args?? 傳遞給服務器的一系列參數。如果為了和inetd兼容,使用了NAMEINARGS flag,則必須指定至少一個參數(服務器名),其他參數可以在服務器名后指定
2. 通過inetd使用socket對象
通常socket對象由socket.socket()調用來建立。但如果你的服務器程序由inetd啟動,那么你需要根據inetd傳給程序的文件描述符,通過調用socket.fromfd()來建立socket對象
socket.fromfd()與socket.socket()相比,多了一個文件句柄的參數
s=socket.fromfd(sys.stdin.fileno(),socket.AF_INET,socket.SOCK_STREAM)
3. 與inetd相關的錯誤處理
由于每個inetd服務器進程只處理一個客戶端,所以服務器進程由于一個錯誤而終止就不是一個嚴重問題
但也不能說一定沒有問題,有些inetd實現,會把stderr傳給客戶端,這時候異常會通過網絡傳給客戶端,這樣會嚴重迷惑客戶端,而且服務器永遠不知道發生了這個問題,這時就需要捕獲錯誤并保持在日志中
1.2 在python中使用syslog
=========================
1. 在開始記錄信息之前,必須調用openlog函數來初始化syslog接口:
openlog(ident[,logopt[,facility]])
1. ident:是一個標識字符從,它會自動加入到每一條日志信息中。通常它是程序名或PID
2. logopt日志選項,可以用Python位運算符或操作符結合
選項名詞???? 描述
------------+--------------------------------------------------------------------------------------------------------------
LOG_CONS???? 當訪問不到機器的syslog進程或記錄信息發生錯誤時,在系統的首選物理Consol上直接顯示該信息
------------+--------------------------------------------------------------------------------------------------------------
LOG_NDELAY?? 不進行任何延時就打開syslog程序的連接,一般情況是當有第一條日志信息時打開
------------+--------------------------------------------------------------------------------------------------------------
LOG_NOWAIT?? 在系統上建立一個新的進程來記錄信息,不用wait()等待集成。有些系統不建立新進程,在這些系統上,這個選項不起作用
------------+--------------------------------------------------------------------------------------------------------------
LOG_PID????? 自動在每條日志信息中包括進程ID
------------+--------------------------------------------------------------------------------------------------------------
LOG_PERROR?? 錯誤除了記錄到syslog中,還會在stderr上打印出來
3. facility工具參數,用來識別產生信息的程序類型
工具名稱???? 描述
------------+------------------------------------------------------------------------------------
LOG_AUTH???? 認證信息:登錄、退出
------------+------------------------------------------------------------------------------------
LOG_CRON???? 來自自動命令日程安排程序的信息
------------+------------------------------------------------------------------------------------
LOG_DAEMON?? 任何不能被歸入日志種類的系統服務器信息
------------+------------------------------------------------------------------------------------
LOG_KERN???? 操作系統的核心信息,python程序中應該盡量少用
------------+------------------------------------------------------------------------------------
LOG_LOCALx?? 從LOG_LOCAL0到LOG_LOCAL7,是為了本地使用,由每一個系統管理員自己定制的。
如果你的應用程序只是在內部用,才能使用這些工具,因為在其他地方,LOG_LOCALx是不同的
------------+------------------------------------------------------------------------------------
LOG_LPR????? 打印服務器信息
------------+------------------------------------------------------------------------------------
LOG_MAIL???? 和郵件有關的信息
------------+------------------------------------------------------------------------------------
LOG_NEW????? Usernet新聞信息
------------+------------------------------------------------------------------------------------
LOG_USER???? 用戶定義的普通信息,該選項默認
------------+------------------------------------------------------------------------------------
LOG_UUCP???? UUCP信息
2. 調用syslog函數記錄信息
syslog([priority,]message)
1. priority被syslog配置文件用來確定對一個給定的信息該如何處理,默認為LOG_INFO
2. syslog優先權說明
優先權名詞??? 描述
-------------+--------------------------------------
LOG_EMERG???? 緊急情況,整個系統非正常關機或不能用
-------------+--------------------------------------
LOG_ALERT???? 給管理員發出警報;需要立即采取措施
-------------+--------------------------------------
LOG_CRIT????? 一個致命錯誤
-------------+--------------------------------------
LOG_ERR?????? 一個普通錯誤
-------------+--------------------------------------
LOG_WARNING?? 一個警告
-------------+--------------------------------------
LOG_NOTICE??? 對于一個重要的正常情況的通知
-------------+--------------------------------------
LOG_INFO????? 普通信息
-------------+--------------------------------------
LOG_DEBUG???? 調試信息;通常丟棄
2 域名系統
~~~~~~~~~~~
2.1 正向查找
=============
1. [(family,socktype,proto,canonname,sockaddr),...]=getaddrinfo(host,port[,family[,socktype[,proto[,flags]]]])
1. host就是要尋找的域名,其他參數只有當想把結果直接傳遞給socke.socket()或socket.connect的時候采用到。
可以設置port為None,然后省略其他參數來進行一個基本的查詢
2. sockaddr就是遠程機器的地址
3. sockaddr是一個tuple,格式為(host,port),主要是為了方便傳入connect()函數
2. socket.gethostbyname()目前只支持IPV4
2.2 反向查找
=============
1. 由于對于一個IP地址,完全有可能不存在反向映射,故對每一個反向查找行為都需要捕獲socket.herror
2. socket.gethostbyaddr(ip)
gethostbyaddr支持IPV6
返回的是一個元組,元素0為hostname,元素2為address
2.3 獲得運行程序機器的域名信息
===============================
1. socket.geethostname()獲取主機名
2. socket.getfqdn(主機名)獲取完整的域名
3. socket.getaddrinfo(完整域名,None)獲取IP
2.4 使用pyDNS
==============
1. 調用DNS.DiscovernameServers()或者直接設置DNS.dausetlf['server']=['ip1','ip2'...]
2. 通過調用DNS.Request()來建立一個請求對象
3. 請求對象的req(name,qtype)執行實際查詢
name為實際查詢的名稱
qtype為record類型
4. 請求對象發出查詢后,返回應答對象,應答對象的answers屬性包含了應答列表
5.
3 高級網絡操作
~~~~~~~~~~~~~~~
3.1 半開發socket
=================
通常socket是雙向的,但如果你想建立一個單向socket,及數據只能在一個方向上傳送(也被稱為半開放socket),需要調用shutdown()函數
對shutdown的調用需要一個單獨參數,來說明你想怎么光比socket。
0?? 禁止將來讀
---+------------
1?? 禁止將來寫
---+------------
2?? 禁止將來讀和寫
一旦給出了關閉的方向,socket就不能在該方向上在重新打開了。
對shutdown的調用時累計的,即調用shutdown(0)后再調用shutdown(1),效果和調用shutdown(2)一樣
3.2 超時
=========
1. 調用socket.settimeout(超時秒數)函數,如果經過超時時間后,什么都沒有發生,則會產生一個socket.timeout異常
3.3 廣播數據
=============
廣播數據不能用TCP實現,它多數使用UDP來實現的
1. 調用socket().setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)來使socket支持廣播
2. 發送的主機使用特殊的地址"",而不是標準的IP地址和主機名
3.4 使用poll()或select()實現事件通知
=====================================
windows不支持poll(),必須使用select()
select()接口早起使用普遍,但比較笨重,而且慢
1. select.poll()調用返回poll對象p
2. p.register(s.fileno(),poll選項集合)注冊希望觀察的socket和poll事件
POLLIN
----------+------------------------------
POLLERR
----------+------------------------------
POLLHUP
----------+------------------------------
POLLOUT??? 至少一個數據包可以被立即發送
----------+------------------------------
POLLPRI??? 準備讀取重要數據
----------+------------------------------
POLLNVAL?? 不正確的請求
3. result=p.poll(等待的毫秒數)? 如果什么都沒發生,則返回空列表,否則返回含有poll事件的列表
4. select(iwtd,owtd,ewtd[,timeout])
iwtd:觀察輸入的文件對象列表
owtd:觀察輸出的文件對象列表
ewtd:觀察錯誤的文件對象列表
timeout:浮點類型,用來指明超時秒數
5. 對select()的調用返回3個tuple,每個tuple都是一個準備好的對象列表,順序與參數一樣
3.5 urllib2
============
1. urllib2.urlopen(url[,post-data])
2. 任何在連接過程中產生的異常要么都是urllib2.URLError的實例,要么是它的一個子類
urllib2.HTTPError的實例很特別,它本身是一種文件類對象,可以迎來讀!讀取的內容就是瀏覽器用來顯示出錯頁面(例如404頁面等)的內容
3. 在讀取數據的時候,會有兩種情況發生:一是通信錯誤,會使socket模塊在調用read()函數時產生socket.error;二是當程序發送文檔時,服務器出現問題或由于文檔被刪除使得發送的文檔被截斷
要檢查第二種情況,一個方法時首先在服務器的回答中找到包頭中記錄的內容長度,然后跟收到的報文長度比較
若內容長度的包頭不被提供,則服務檢查出這種錯誤。
4. urlib2.urlopen().info()函數返回報文頭字典
4 解析HTML和XHTML
~~~~~~~~~~~~~~~~~~
4.1 使用HTMLParser模塊解析HTML
===============================
1) 你需要定義一個HTMLParser.HTMLParser的子類,并實現處理不同標簽的函數
2) 需要定義的函數有
handle_starttag(self,tag,attrs)
handle_data(self,data)
handle_endtag(self,tag)
handle_entityref(self,name)???????????????? #當出現實體的時候調用,在htmlentitydefs類中提供了HTML實體的映射
handle_charref(self,name)?????????????????? #當出現字符參考時調用++-
3) HTMLParser的feed()方法會適當地調用handle_starttag(),handle_data(),handle_endtag(),handle_entityref()方法
4.2 XML和XML-RPC
=================
1. SAX是基于事件模型的,DOM是基于樹的
4.2.1 DOM模型
--------------
4.2.2 xmlrpclib庫
------------------
5 E-mail服務
~~~~~~~~~~~~~
5.1 E-mail的編寫和編碼
=======================
1. 每一個傳統的Email都包含兩個不同部分:header和body。header包含控制數據,例如寄件人、目的地、信息的標題。body保安信息本身。最開始總是header,然后是body.header和body之間由一個空行區分
2. 發送郵件給誰,由SMTP攜帶這些信息。跟header其實無關
3. 產生郵件的模塊安裝在email模塊中,一般用email.MIMEText模塊中的MIMEText類或email.Message.Message
使用email.Utils.make_msgid()來得到Message-ID header
使用email.Utils.formatdate()來得到Date header
from email.MIMEText import MIMEText
from email import Utils
message="hello"
msg=MIMEText(message)
msg['To']='reciver@example.com'
msg['From']='sender@example.com'
msg['Subject']='Test message'
msg['Date']=Utils.formatdate(localtime=1)
msg['Message-ID']=Utils.make_msgid()
print msg.as_string()
4. 使用email.message_from_file(fd)來解析郵件
5. 使用email.Utils.mktime_tz與email.Utils.parsedate_tz()函數聯合起來解析郵件的date header
parsedate_tz()載入一個日期字符串,返回一個10個元素的tuple,如果輸入有誤則得不到
tuple的前9個元素可以傳遞給time.mktime(),
還有一個mktime_tz()函數可以理解全部的10個元素,把它轉換成一個標準的,從新紀元開始至今的秒數
6. MIME
1. 一般約定,最基本的內容(純文本郵件)會出現在最前面,這樣沒有識別MIME的郵件程序也可用閱讀純文件
2. 添加MIME附件的方法
1. 建立一個MIMEMultipart()對象,設置郵件的header
2. 為郵件內容部分建立一個MIMEText()對象,把它放到MIMEMultipart對象中
3. 為每一個附件建立一個合適的MIME對象,也把它放到MIMEMultipart()對象中
4. 調用MIMEMultipart()對象中的as_string()函數來得到作為結果的郵件
def p_w_upload(filename):
fd=open(filename,'rb')
mimetype,mimeencoding=mimetypes.guess_type(filename)
if mimeencoding or (mimetype is None):
mimetype='application/octet-stream'
maintype,subtype=mimetype.split('/')
if maintype == 'text':
retval=MIMEText(fd.read(),_subtype=subtype)
else:
retval=MIMEBase(maintype,subtype)
retval.set_payload(fd.read())
Encoders.encode_base64(retval)
retval.add_header('Content-Disposition','p_w_upload',filename=filename)
fd.close()
return retval
3. MIME替換方法
MIME替換方法可以產生一個單獨文件的多個版本,用戶的郵件程序會自動決定顯示哪個
替換方法和添加附件的方法的區別在于不需要Content-Disposition header:
def p_w_upload(filename):
fd=open(filename,'rb')
mimetype,mimeencoding=mimetypes.guess_type(filename)
if mimeencoding or (mimetype is None):
mimetype='application/octet-stream'
maintype,subtype=mimetype.split('/')
if maintype == 'text':
retval=MIMEText(fd.read(),_subtype=subtype)
else:
retval=MIMEBase(maintype,subtype)
retval.set_payload(fd.read())
Encoders.encode_base64(retval)
#替換方法和添加附件的方法的區別在于不需要Content-Disposition header
fd.close()
return retval
4. 構建非英語的header
email.Header模塊中的Header類,可以實現用指定字符集編碼頭數據
from email.Header import Header
fromhdr=Header("盧俊蔚",'utf-8')
fromhdr.append('','ascii')
msg['From']=fromhdr
Email地址使用另外的字符集單獨添加,否則,編碼車功能需就會對Email地址編碼,不含MIME功能的程序就不能回復該郵件
5. 解碼header
使用email.Header.decode_header(x)可以返回一個header內容的列表。
列表中列表項的格式為(header的獨立編碼部分,編碼文件的字符集)
若header沒有編碼,即為ascii,則返回的字符集為None
6.
5.2 SMTP
=========
1. 使用smtplib發送郵件
s=smtplib.SMTP(server)
s.sendmail(fromaddr,toaddrList,message)
這里message包含header信息,可以用email模塊來構建
另外,只有sendmail()的收件人才能決定誰收到郵件,跟header的To和Cc無關
2. 使用smtplib時可能產生的錯誤
socket.gaierror???????? 尋找地址時出現的錯誤
-----------------------+----------------------
socket.error??????????? 普通IO和通訊錯誤
-----------------------+----------------------
socket.herror?????????? 其他地址錯誤
-----------------------+----------------------
smtplib.SMTPException?? SMTP會話問題
3. 通過smtp().set_debuglevel(1)可以開啟smtplib的調試模式,它提供了基本的錯誤處理和調試
開啟了調試模式之后,就能看出smtplib和SMTP服務器
4. HELO和EHLO
SMTP的初始版本中,客戶端會向服務器發送一個HELO指令作為初始問候。
SMTP的一系列擴展,稱為ESMTP,具有ESMTP功能的服務端會開始EHLO會話,它提示具有ESMTP功能的服務器發送擴展信息。這個信息除了正常信息外,還包括郵件最大容量
多數現代郵件服務器支持EHLO,服務器會返回它支持的可選SMTP特征的信息
在一些不支持ESMTP的服務器上,EHLO會返回一個錯誤,這是你必須發送HELO命令
如果手工調用了EHLO或HELO指令,sendmail不會再試圖自動發送這些指令了
s=smtplib.SMTP(server)
code=s.ehlo()[1]
if not (200<=code<=299):
code=s.helo()[1]
if not (200<=code<=299):
raise SMTPHeloError(code,resp)
5. SMTP使用TLS層加密
1. 像通常那樣建立SMTP對象
2. 發送EHLO指令。如果遠程主機不支持EHLO,它不支持TLS
3. 檢查啊s.has_ext(),看它是否提供starttls。如果不提供,遠程主機不支持TLS,郵件需要以正規方法發送
4. 調用starttls()來初始化通道
5. 再次調用ehlo(),這次它是加密的了
6. 左后,像往常一樣發送郵件
6. SMTP實現認證
SMTP().login(username,password)
如果你使用的服務器不支持認證,你會收到一個'Authentication failed"錯誤提示。可以在調用s.ehlo()后使用s.has_extn('auth')來避免這個錯誤
5.3 POP協議
============
1. 連接和認證
1. 建立一個pop3對象,傳給它遠程服務器的主機名和端口號
2. 調用user()和pass_()函數來發送用戶名和密碼
3. 如果產生poplib.error_proto異常,登錄就失敗,服務器會發送和異常有關的字符串和解釋文字
4. 若使用APOP認證,則調用POP3().apop(user,passwd)來認證
5. 若認證失敗,則拋出poplib.error_proto異常
2. 取得郵箱信息
1. pop3().stat()返回一個tuple,其中包含了服務器郵件中郵件數量和郵件總大小
2. pop3().list()會返回每一封郵件更詳細的信息。list函數返回一個包含兩個條目的tuple,第一個是應答代碼,另一個是字符串的List。
列表的每一個字符也包含兩個條目,中間有一個空格:郵件的數字和郵件的字節數
3. 下載郵件
1. pop3().retr(郵件數字),每次下載一封郵件
2. retr()函數返回一個tuple,其中包含了結果代碼和郵件。但郵件不是字符串格式的,而是一個字符串的列表,每個元素代表該郵件的一行
4. 刪除郵件
pop().dele(郵件編號),每次只刪除一個文件。
大多數POP服務器只有在你調用了quit()之后,才會真正刪除這些郵件
5.4 TODO IMAP協議
==================
1. Twisted中的IMAP
6 FTP
~~~~~~
1. ftplib
1. 如果只是想下載文件的話,用urllib2模塊比ftplib更簡單
2. ftplib.FTP實例的函數
f=FTP(ftp服務器地址)??????????????????? 新建一個FTP對象
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.getwelcome()????????????????????????? 獲取歡迎信息
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.login([username,password])??????????? 登錄ftp
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.pwd()???????????????????????????????? 獲取當前工作目錄
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.cwd(遠程目錄)???????????????????????? 在遠程系統上轉換目錄
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.retrlines(運行的指令,回調函數)??????? 以ASC模式下載文件。retrlines函數的第一個參數指定一個在遠程系統運行的指令,這個參數一般是RETR,后面是文件名。
它的第二個參數是一個函數,客戶端沒收到一行數據后都會運行一次這個函數;
如果第二個參數被省略,數據會輸出到標準輸出設備上來。
數據在傳輸的時候,每一行的行尾都會去掉
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.retrbinary(運行的指令,回調函數??????? retrbinary函數可以向指定的函數傳輸整塊的數據
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.voidcmd(FTP指令)????????????????????? 直接向FTP服務器傳輸一條指令,檢查有沒有錯誤,但該函數不返回任何結果
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.ntransfercmd(FTP下載/上傳指令) 例如?? 以高級二進制模式下載/上傳文件。
f.ntransfercmd('RETR linux.tar')??????? 該函數返回一個tuple:(數據的socket,數據大小的估計值)。注意,該估計值不是精確的,如果FTP服務器上得不到估計值,則估計值為None
f.ntransfercmd('STOR linux.tar')??????? 在接受完數據后,要關閉數據socket并調用voidresp()函數
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.voidresp()??????????????????????????? 獲得FTP服務器的響應,如果發現任何錯誤就報錯
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.storbinary(STOR命令,文件類型fd)?????? 實現二進制上傳,注意與下載函數不同,第二個參數為文件類型對象,而下載函數的第二個參數為函數
storbinary()調用的是傳入文件類型對象的read()方法
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.storlines(STOR命令,文件類型fd)??????? 實現文本格式上傳。
storlines()函數調用的是文件類型對象的readline()方法
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.nlst()??????????????????????????????? 返回服務器上當前目錄下的一系列條目,但僅能獲得文件和目錄列表,而無其他信息
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.dir(回調函數)???????????????????????? 從遠方服務器上返回一個目錄列表,這個列表格式根據FTP服務器操作系統的不同而定,包括詳細信息,返回的每一行都會送入回調函數處理
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.delete(文件名)??????????????????????? 刪除文件
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.rmd(目錄名)?????????????????????????? 刪除目錄
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
f.mkd(目錄名)?????????????????????????? 新建一個目錄
---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------
rename(舊文件名,新文件名)?????????????? 跟UNIX的mv指令一樣
7 數據庫
~~~~~~~~~
1. 參數風格說明
通過查看數據庫模塊的paramstyle變量來查看
1. qmark:
表示question-mark風格。指令字符串中的數據的每一位都用一個問號替換,參數以list或tuple的形式給出。
Insert into ch14 value(?,?)
2. format:
使用和printf一樣的類型格式,不支持對于指定參數python的擴展名。它帶一個list或tuple來轉換
Insert into ch14 values(%d,%s)
3. nueric:
指令字符串中的數據的每一位都被一個后面是數字的冒號代替,數字從1開始,參數以list或tuple給出
insert into ch14 values(:1,:2)
4. named:
和numeric類似,但是冒號后面用名稱取代數字,用一個dictionary轉換
Insert into ch14 values(:number,:text)
5. pyformat:
至此和Python風格的參數,帶dictionary轉換
insert into ch14 values(%(number)d,%(text)s)
2. 使用executemany()一次執行多個SQL語句
executemany()函數帶一個指令和一列該指令運行的記錄。記錄上的每條記錄為一個list或dictionary,著取決于數據庫模塊的參數風格
import sqlite3
values=([1,'one'],[2,'two'],[3,'three'])
cur=sqlite3.connect().cursor()
cur.executemany("insert into ch14 values(?,?)",values)
cur.execute("insert into ch14 values(?,?)",[5,'five'])
3. 獲取數據
cursor.fetchall()??????????? 獲取所有記錄
----------------------------+-----------------------------------------------------
cursor.fetchmany([number])?? 通過設置cursor的arraysize屬性來決定每次返回的結果數
或者傳遞給fetchmany一個指定的大小
----------------------------+-----------------------------------------------------
cursor.fetchone()??????????? 返回單獨行,若沒有數據了返回None
4. 元數據
除了通過查詢的數據外,數據庫服務器還可用返回metadata,這個metadata包含一些諸如結果名稱和類型的信息
可以通過cursor.description來獲得metadata
5. Python與SQL類型轉換
1. Binary():
帶一個字符串,并產生一個二進制對象,該對象主要設計城保存大的二進制數據
2. Date():
帶一個整數的年月日,產生一個日期對象,其中年能使用2位的簡化表示方法
3. DateFromTicks():
帶一個整數或者浮點數,表示UNIX新紀元到現在的秒數,產生一個日期對象。參數和time.time()格式一樣
4. Time():
帶小時(24小時格式),分,秒,都是整數,產生時間對象
5. TimeFromTicks():
類似DateFromTicks
6. Timestamp():
帶一個年(不能2位表示),月,日,時,分,秒,產生一個timestamp類
7. TimestampFromTicks()
類似DateFromTicks
8 SSL
~~~~~~
1. 內置SSL
1. 建立一個SSL類型
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("www.openssl.org",443))
ssl=socket.ssl(s)
2. ssl對象只提供兩個方法:read()和write(0
2. pyOpenSSL
1. 建立一個SSL類型
from OpenSSL import SSL
ctx=SSL.Context(SSL.SSLv23_METHOD)
s=socket.socket(socket.AF_INET,socket_SOCK_STREAM)
ssl=SSL.Connection(ctx,s)
ssl.connect(('www.openssl.org',443))
ssl.sendall("xxx")
buf=ssl.recv(4098)
9 SocketServer
~~~~~~~~~~~~~~~
SocketServer是Python的框架,用來在服務器上處理來自客戶端的請求。
SocketServer非常適合編寫那種接受一個請求并返回一個應答的服務器程序。
SocketServer相關類一樣,它定義了兩個類,一個Server對象類,一個request處理類
1. BaseHTTPServer
Server類:HTTPServer
request處理類:BaseHTTPRequestHandler
1. 建立一個BaseHTTPServer
class Requesthandler(BaseHTTPRequestHandler):
pass
serveraddr=('',8765)
srvr=HTTPServer(serveraddr,RequestHandler)
srvr.serve_forever()
為了實現自己的HTTP服務器,需要定義一個BaseHTTPRequesthandler的子類。
2. BaseHTPRequestHandl類提供了一些方便的方法
send_response()
send_header()
end_headers()
還提供了rfile和wfile變量提供直接存取數據流,并發送回文檔
3. 需要自定義的方法有
do_GET(self)
do_HEAD(self)
do_POST(self)
4. 可以通過同時繼承自定義的BaseHTTPRequesthandler的子類和ThreadingMixIn的方式,使得HttpServer實現多線程服務
2. SimpleHTTPServer
Server類:simpleHTTPServer
request處理類:SimpleHTTPRequestHandler
3. CGIHTTPServer
Server類:CGIHTTPServer
request處理類:CGIHTTPRequestHandler
4. 使用SocketServer模塊中的TCPServer/UDPServer和StreamRequestHandler/DatagramRequestHandler等類來實現自己的協議
TCPServer/UDPServer收到請求后會調用和StreamRequestHandler/DatagramRequestHandler子類中的handler()方法來處理請求
BaseRequestHandler(及其子類如StreamRequestHandler類等)會初始化一些變量,這些變量包含了客戶端和環境變量的信息。如request,client_address
10 SimpleXMLRPCServer
~~~~~~~~~~~~~~~~~~~~~~
1. 建立一個服務器
srvr=SimpleXMLRPCServer(serverAddr,SimpleXMLRPCRequestHandler)
2. 注冊一個實例/函數
srvr.register_instance(Math())
srvr.register_introspection_functions()
/
srvr.register_function(函數名詞)
srvr.register_function(list.sort)????????? #這個返回值為None,調用會報錯
需要注意的是,注冊的函數必須是不能為None的,因為默認通常表示出問題了。
如果真要接受None,可以愛建立Server實例時,設置allow_none為true
另外,XML-RPC不能發送Python自定義的類對象,所以參數和返回值必須是簡單數據類型,list和dictionary
3. 啟動服務
srvr.serve_forever()
4. DocXMLRPCServer模塊使客戶端可以用Web瀏覽器查看XML-RPC產生的每個方法描述
5. CGIXMLRequestHandler類(SimpleXMLRPCServer模塊的一部分)可以把CGI腳本轉換成XML-RPC服務器
需要注意的是,使用是這個類需要用用在CGI腳本中,供Web服務器調用的
handler=CGIXMLRPCRequestHandler()
handler.register_instance(Math())
handler.register_introspection_functions()
handler.handle_request()
6. 啟用Multicall
Multicall是對標準XML-RPC的一個非正式補充,它使客戶端一次向XML-RPC服務器提交多個請求
srvr.register_multicall_functions()
srvr.serve_forever()
總結
以上是生活随笔為你收集整理的python网络编程证书_《Python网络编程基础》笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vb excel遍历列_EXCEL如何把
- 下一篇: python文件数据总和计算_pytho