轉載請註明:@小五義 http://www.cnblogs.com/xiaowuyi
看了這一節,突然之間對python網路編程學習筆記(1)中的一些不理解的問題有了認識,至少明白了socket是怎麼回事。這裡關於socket的起源等問題就不做筆記記錄了,直接進入主題。
1、建立socket
建立socket對象需要搞清通訊類型和協議家族。通訊類型指明了用什麼協議來傳輸資料。協議的例子包括IPv4、IPv6、IPX\SPX、AFP。對於internet通訊,通訊類型基本上都是AF_INET(和IPv4對應)。協議家族一般表示TCP通訊的SOCK_STREAM或者表示UDP通訊的SOCK_DGRAM。因此對於TCP通訊,建立一個socket串連的語句為:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
對於UDP通訊,建立一個socket串連的語句為:
s=socket.socket(socket.AF_INET,SOCK_DGRAM)
2、串連socket
串連socket需要提供一個tuple,包括host(主機名稱或者IP)和port(遠程連接埠),類似代碼為:
s.connect(("www.baidu.com",80)
3、尋找連接埠號碼
socket庫中利用getservbyname()函數可以查詢連接埠號碼,一般需要兩個參數:一是協議名,如http、smtp、pop3等,一個是連接埠名,如tcp、udp
例如:
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
port=socket.getservbyname('http','tcp')
port的傳回值為80。若改為:
port=socket.getservbyname('smtp','tcp')
port的傳回值為25。
4、從socket擷取資訊
建立socket串連後,可以通過getsockname()擷取本身的ip地址和連接埠號碼,也可以通過getpeername()顯示遠程機器的ip地址和連接埠號碼。
如:在python shell中
>>> import socket
>>> s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
>>> port=socket.getservbyname('http','tcp')
>>> s.connect(('www.baidu.com',port))
>>> print s.getsockname()
('192.168.87.138', 3213)
>>> print s.getpeername()
('220.181.111.147', 80)
Socket 模組的類方法
類方法 說明
Socket 低層網路介面(每個 BSD API)
socket.socket(family, type) 建立並返回一個新的 socket 對象
socket.getfqdn(name) 將使用點號分隔的 IP 位址字串轉換成一個完整的網域名稱
socket.gethostbyname(hostname) 將主機名稱解析為一個使用點號分隔的 IP 位址字串
socket.fromfd(fd, family, type) 從現有的檔案描述符建立一個 socket 對象
Socket 模組的執行個體方法
執行個體方法 說明
sock.bind( (adrs, port) ) 將 socket 綁定到一個地址和連接埠上
sock.accept() 返回一個客戶機 socket(帶有客戶機端的地址資訊)
sock.listen(backlog) 將 socket 設定成監聽模式,能夠監聽 backlog 外來的串連請求
sock.connect( (adrs, port) ) 將 socket 串連到定義的主機和連接埠上
sock.recv( buflen[, flags] ) 從 socket 中接收資料,最多 buflen 個字元
sock.recvfrom( buflen[, flags] ) 從 socket 中接收資料,最多 buflen 個字元,同時返回資料來源的遠程主機和連接埠號碼
sock.send( data[, flags] ) 通過 socket 發送資料
sock.sendto( data[, flags], addr ) 通過 socket 發送資料
sock.close() 關閉 socket
sock.getsockopt( lvl, optname ) 獲得指定 socket 選項的值
sock.setsockopt( lvl, optname, val ) 設定指定 socket 選項的值
舉例:
>>> import socket
>>> socket.gethostbyname('www.baidu.com')
'220.181.111.147'
>>> socket.gethostbyname('www.126.com')
'123.125.50.22'
>>> socket.getfqdn('123.125.50.22')
'123.125.50.22'
這裡getfqdn卻不能返回網域名稱?
5、處理錯誤
關於錯誤異常的處理,主要就是用try、except語句。如將python網路編程學習筆記(1)中gopherclient.py進行一下修改:
# -*- coding: cp936 -*-##modify by 小五義 http://www.cnblogs.com/xiaowuyiimport socket,sysport =70host=sys.argv[1]filename=sys.argv[2]try: s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)except Socket.error,e: print "建立socket錯誤:%s"%etry: s.connect((host,port))except socket.gaierror,e: print "host或者連接埠錯誤:%s" %eexcept socket.error,e: print "串連錯誤:%s" %etry: s.sendall(filename+"\r\n")except socket.error,e: print "資料發送錯誤:%s" %e sys.exit(1)while 1: try: buf=s.recv(2048) except socket.error,e: print "接收錯誤:%s"%e sys.exit(1) if 'does not exist' in buf: print "%s檔案不存在" %filename else: if not len(buf): break sys.stdout.write(buf)
運行結果是:
C:\>python gopherclient.py quux.org/ wh.txt
串連錯誤:[Errno 10060]
資料發送錯誤:[Errno 10057] 由於通訊端沒有串連並且(當
據報通訊端時)
C:\>python gopherclient.py quux.org wh.txt
wh.txt檔案不存在
=======================================================================================================================
對python網路編程學習筆記(1)的添加
筆記1中在dos下運行python gopherclient.py quux.org系統提示出錯的問題,終於明白了。錯誤原因是少了檔案名稱。如在quux.org/有whatsnew.txt,於是在dos下運行python gopherclient.py quux.org whatsnew.txt。這時會將whatsnew.txt的內容全部列出。