python網(wǎng)絡(luò)編程學(xué)習(xí)筆記(一)
學(xué)習(xí)用書(shū):《python 網(wǎng)絡(luò)編程基礎(chǔ)》作者John Goerzen
第一部分底層網(wǎng)絡(luò)學(xué)習(xí)
Python提供了訪問(wèn)底層操作系統(tǒng)Socket接口的全部方法,需要的時(shí)候這些接口可以提供靈活而強(qiáng)有力的功能。
(1)基本客戶端操作
在《python 網(wǎng)絡(luò)編程基礎(chǔ)》一書(shū)中,作者列出了一個(gè)簡(jiǎn)單的Python客戶端程序,具體如下:
import socket,sys
port =70
host=sys.argv[1]
filename=sys.argv[2]
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))
s.sendall(filename+"\r\n")
while 1:
buf=s.recv(2048)
if not len(buf):
break
sys.stdout.write(buf)
該程序?qū)崿F(xiàn)的是Gopher協(xié)議,實(shí)現(xiàn)從主機(jī)上請(qǐng)求相關(guān)文檔的功能。(Gopher是Internet上一個(gè)非常有名的信息查找系統(tǒng),它將Internet上的文件組織成某種索引,很方便地將用戶從Internet的一處帶到另一處。在WWW出現(xiàn)之前,Gopher是Internet上最主要的信息檢索工具,Gopher站點(diǎn)也是最主要的站點(diǎn)。但在WWW出現(xiàn)后,Gopher失去了昔日的輝煌?,F(xiàn)在它基本很少被使用。)
于是,我按照書(shū)上的語(yǔ)句進(jìn)行了一下測(cè)試,在dos下運(yùn)行python gopherclient.py quux.org。但是系統(tǒng)提示為
Traceback (most recent call last):
File "gopherclient.py", line 5, i
filename=sys.argv[2]
IndexError: list index out of range
看了一下,sys.argv只有兩個(gè)元素['gopherclient.py', 'quux.org/']所以filename=sys.argv[2]就超出下界了??墒菫槭裁磿?huì)出現(xiàn)這個(gè)原因呢?是書(shū)里面寫錯(cuò)了嗎,因?yàn)槲乙彩浅鯇W(xué)socket,不是很了解,所以我也是沒(méi)有找到原因,如果哪位大牛知道是什么原因,希望能給講解一下。
(2)基本服務(wù)器操作
《python 網(wǎng)絡(luò)編程基礎(chǔ)》一書(shū)中同樣給出了一個(gè)簡(jiǎn)單的服務(wù)器程序,具體如下:
import socket
host=''
port=51423
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host,port))
s.listen(1)
print "Server is running on port %d;press Ctrl-C to terminate." %port
while 1:
clientsock,clientaddr=s.accept()
clientfile=clientsock.makefile('rw',0)
clientfile.write("welcome,"+str(clientaddr)+'\n')
clientfile.write("Please enter a string:")
line=clientfile.readline().strip()
clientfile.write("You entered %d characters.\n" %len(line))
clientfile.close()
clientsock.close()
該程序運(yùn)行后,提示“Server is running on port 51423:press Ctrl-C to terminate”。此時(shí),通過(guò)另一臺(tái)機(jī)器telnet本機(jī)器的51423端口,如telnet 127.0.0.1:51423,此時(shí)會(huì)提示welcome 127.0.0.1 ****,please enter a string:。 然后輸入幾個(gè)字符后,會(huì)返回你輸入字符的個(gè)數(shù)。
這里就該程序進(jìn)行一下分析:
1、首先導(dǎo)入socket模塊,給host和port賦值。
2、調(diào)用socket.socket()來(lái)建立一個(gè)socket賦值給s。socket.socket(domain, type, protocol).domain參數(shù)的值有AF_UNIX,AF_LOCAL,AF_INET,PF_UNIX,PF_LOCAL,PF_INET。這幾個(gè)值中AF_UNIX=AF_LOCAL, PF_UNIX=PF_LOCAL, AF_LOCAL=PF_LOCAL, AF_INET=PF_INET。一般來(lái)說(shuō),AF 表示ADDRESS FAMILY 地址族,PF 表示PROTOCOL FAMILY 協(xié)議族,但這兩個(gè)宏定義是一樣的,所以使用哪個(gè)都沒(méi)有關(guān)系。參數(shù)type指定socket的類型:SOCK_STREAM提供有序、可靠、雙向及基于連接的字節(jié)流。SOCK_DGRAM支持?jǐn)?shù)據(jù)報(bào)。SOCK_SEQPACKET提供有序、可靠、雙向及基于連接的數(shù)據(jù)報(bào)通信。SOCK_RAW提供對(duì)原始網(wǎng)絡(luò)協(xié)議的訪問(wèn)。SOCK_RDM提供可靠的數(shù)據(jù)報(bào)層,但是不保證有序性。protocol一般取0(為什么取0我也沒(méi)搞清楚,放在以后明白了再寫上吧)。
3、s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)。setsockopt()函數(shù)用于任意類型、任意狀態(tài)套接口的設(shè)置選項(xiàng)值。盡管在不同協(xié)議層上存在選項(xiàng),但本函數(shù)僅定義了最高的“套接口”層次上的選項(xiàng)。選項(xiàng)影響套接口的操作,諸如加急數(shù)據(jù)是否在普通數(shù)據(jù)流中接收,廣播數(shù)據(jù)是否可以從套接口發(fā)送等等。 這個(gè)函數(shù)中,第一個(gè)參數(shù)為協(xié)議層參數(shù),指明了希望訪問(wèn)一個(gè)選項(xiàng)所在的協(xié)議棧。通常我們需要使用下面中的一個(gè):
SOL_SOCKET來(lái)訪問(wèn)套接口層選項(xiàng)
SOL_TCP來(lái)訪問(wèn)TCP層選項(xiàng)
第二個(gè)參數(shù)是與第一個(gè)參數(shù)相對(duì)應(yīng)的。第一個(gè)參數(shù)決定了協(xié)議層level,第二個(gè)參數(shù)決定了該協(xié)議層下選項(xiàng)組合。SOL_SOCKET的選項(xiàng)組合如下:
協(xié)議層 選項(xiàng)名字
SOL_SOCKET SO_REUSEADDR
SOL_SOCKET SO_KKEPALIVE
SOL_SOCKET SO_LINGER
SOL_SOCKET SO_BROADCAST
SOL_SOCKET SO_OOBINLINE
SOL_SOCKET SO_SNDBUF
SOL_SOCKET SO_RCVBUF
SOL_SOCKET SO_TYPE
SOL_SOCKET SO_ERROR
具體的一些組合用法可見(jiàn):http://wenku.baidu.com/view/23013b7101f69e3143329402.html
第三個(gè)參數(shù)設(shè)為1,這里我也沒(méi)很明白其中的意思,我試著把1換成50,結(jié)果是一樣的。換成0也是可以的,沒(méi)發(fā)現(xiàn)什么區(qū)別。希望大牛們給指點(diǎn)一下。
4、s.bind((host,port))綁定主機(jī)端口。
5、s.listen(1):listen函數(shù)使用主動(dòng)連接套接口變?yōu)楸贿B接套接口,使得一個(gè)進(jìn)程可以接受其它進(jìn)程的請(qǐng)求,從而成為一個(gè)服務(wù)器進(jìn)程。在TCP服務(wù)器編程中l(wèi)isten函數(shù)把進(jìn)程變?yōu)橐粋€(gè)服務(wù)器,并指定相應(yīng)的套接字變?yōu)楸粍?dòng)連接。這里的參數(shù)涉及到一些網(wǎng)絡(luò)的細(xì)節(jié)。在進(jìn)程正理一個(gè)一個(gè)連接請(qǐng)求的時(shí)候,可能還存在其它的連接請(qǐng)求。因?yàn)門CP連接是一個(gè)過(guò)程,所以可能存在一種半連接的狀態(tài),有時(shí)由于同時(shí)嘗試連接的用戶過(guò)多,使得服務(wù)器進(jìn)程無(wú)法快速地完成連接請(qǐng)求。如果這個(gè)情況出現(xiàn)了,服務(wù)器進(jìn)程希望內(nèi)核如何處理呢??jī)?nèi)核會(huì)在自己的進(jìn)程空間里維護(hù)一個(gè)隊(duì)列以跟蹤這些完成的連接但服務(wù)器進(jìn)程還沒(méi)有接手處理或正在進(jìn)行的連接,這樣的一個(gè)隊(duì)列內(nèi)核不可能讓其任意大,所以必須有一個(gè)大小的上限。這個(gè)backlog告訴內(nèi)核使用這個(gè)數(shù)值作為上限。毫無(wú)疑問(wèn),服務(wù)器進(jìn)程不能隨便指定一個(gè)數(shù)值,內(nèi)核有一個(gè)許可的范圍。這個(gè)范圍是實(shí)現(xiàn)相關(guān)的。很難有某種統(tǒng)一,一般這個(gè)值會(huì)小30以內(nèi)。這里設(shè)定為1表示每次最多只有一個(gè)等候處理的連接。
6、while循環(huán)從accept()函數(shù)開(kāi)始。程序會(huì)在連接了一個(gè)客戶端后關(guān)閉socket。當(dāng)某個(gè)客戶端連接的時(shí),accept返回兩個(gè)信息,一個(gè)新的連接客戶端socket和客戶端的ip地址、端口號(hào)。如在上面的例子中添加print語(yǔ)句輸出clientsock和clientaddr,你會(huì)發(fā)現(xiàn)clientsock為socket.socketobject,clientaddr=('客戶端Ip',端口)。后面的循環(huán)中使用了文件類對(duì)象,服務(wù)器接著顯示出一些介紹性信息,從客戶端讀一個(gè)字符串,顯示一個(gè)應(yīng)答,最后關(guān)閉客戶端socket。
相關(guān)文章
python3+PyQt5使用數(shù)據(jù)庫(kù)窗口視圖
這篇文章主要為大家詳細(xì)介紹了python3+PyQt5使用數(shù)據(jù)庫(kù)窗口視圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04使用Python-OpenCV消除圖像中孤立的小區(qū)域操作
這篇文章主要介紹了使用Python-OpenCV消除圖像中孤立的小區(qū)域操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07Python簡(jiǎn)單實(shí)現(xiàn)安全開(kāi)關(guān)文件的兩種方式
這篇文章主要介紹了Python簡(jiǎn)單實(shí)現(xiàn)安全開(kāi)關(guān)文件的兩種方式,涉及Python的try語(yǔ)句針對(duì)錯(cuò)誤的判定與捕捉相關(guān)技巧,需要的朋友可以參考下2016-09-09如何獲取Python簡(jiǎn)單for循環(huán)索引
這篇文章主要介紹了如何獲取Python簡(jiǎn)單for循環(huán)索引,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11Python讀取和處理文件后綴為.sqlite的數(shù)據(jù)文件(實(shí)例講解)
下面小編就為大家?guī)?lái)一篇Python讀取和處理文件后綴為.sqlite的數(shù)據(jù)文件(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06python中with語(yǔ)句結(jié)合上下文管理器操作詳解
這篇文章主要給大家介紹了關(guān)于python中with語(yǔ)句結(jié)合上下文管理器操作的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-1268行Python代碼實(shí)現(xiàn)帶難度升級(jí)的貪吃蛇
本文主要介紹了Python代碼實(shí)現(xiàn)帶難度升級(jí)的貪吃蛇,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01python3實(shí)現(xiàn)語(yǔ)音轉(zhuǎn)文字(語(yǔ)音識(shí)別)和文字轉(zhuǎn)語(yǔ)音(語(yǔ)音合成)
這篇文章主要介紹了python3實(shí)現(xiàn)語(yǔ)音轉(zhuǎn)文字(語(yǔ)音識(shí)別)和文字轉(zhuǎn)語(yǔ)音(語(yǔ)音合成),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10