學習用書:《python 網路程式設計基礎》作者john goerzen
第一部分底層網路學習
python提供了訪問底層作業系統socket介面的全部方法,需要的時候這些介面可以提供靈活而強有力的功能。
(1)基本客戶端操作
在《python 網路程式設計基礎》一書中,作者列出了乙個簡單的python客戶端程式,具體如下:
importsocket,sys
port =70host=sys.ar**[1]
filename=sys.ar**[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)
ifnot
len(buf):
break
sys.stdout.write(buf)
該程式實現的是gopher協議,實現從主機上請求相關文件的功能。(gopher是internet上乙個非常有名的資訊查詢系統,它將internet上的檔案組織成某種索引,很方便地將使用者從internet的一處帶到另一處。在www出現之前,gopher是internet上最主要的資訊檢索工具,gopher站點也是最主要的站點。但在www出現後,gopher失去了昔日的輝煌。現在它基本很少被使用。)
於是,我按照書上的語句進行了一下測試,在dos下執行python gopherclient.py quux.org。但是系統提示為
traceback (most recent call last):
file "gopherclient.py", line 5, i
filename=sys.ar**[2]
indexerror: list index out of range
看了一下,sys.ar**只有兩個元素['gopherclient.py', 'quux.org/']所以filename=sys.ar**[2]就超出下界了。可是為什麼會出現這個原因呢?是書裡面寫錯了嗎,因為我也是初學socket,不是很了解,所以我也是沒有找到原因,如果哪位大牛知道是什麼原因,希望能給講解一下。
(2)基本伺服器操作
《python 網路程式設計基礎》一書中同樣給出了乙個簡單的伺服器程式,具體如下:
importsocket
host=''
port=51423s=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)
"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()
該程式執行後,提示「server is running on port 51423:press ctrl-c to terminate」。此時,通過另一台機器telnet本機器的51423埠,如telnet 127.0.0.1:51423,此時會提示welcome 127.0.0.1 ****,please enter a string:。 然後輸入幾個字元後,會返回你輸入字元的個數。
這裡就該程式進行一下分析:
1、首先匯入socket模組,給host和port賦值。
2、呼叫socket.socket()來建立乙個socket賦值給s。socket.socket(domain, type, protocol).domain引數的值有af_unix,af_local,af_inet,pf_unix,pf_local,pf_inet。這幾個值中af_unix=af_local, pf_unix=pf_local, af_local=pf_local, af_inet=pf_inet。一般來說,af 表示address family 位址族,pf 表示protocol family 協議族,但這兩個巨集定義是一樣的,所以使用哪個都沒有關係。引數type指定socket的型別:sock_stream提供有序、可靠、雙向及基於連線的位元組流。sock_dgram支援資料報。sock_seqpacket提供有序、可靠、雙向及基於連線的資料報通訊。sock_raw提供對原始網路協議的訪問。sock_rdm提供可靠的資料報層,但是不保證有序性。protocol一般取0(為什麼取0我也沒搞清楚,放在以後明白了再寫上吧)。
3、s.setsockopt(socket.sol_socket,socket.so_reuseaddr,1)。setsockopt()函式用於任意型別、任意狀態套介面的設定選項值。儘管在不同協議層上存在選項,但本函式僅定義了最高的「套介面」層次上的選項。選項影響套介面的操作,諸如加急資料是否在普通資料流中接收,廣播資料是否可以從套介面傳送等等。 這個函式中,第乙個引數為協議層引數,指明了希望訪問乙個選項所在的協議棧。通常我們需要使用下面中的乙個:
sol_socket來訪問套介面層選項
sol_tcp來訪問tcp層選項
第二個引數是與第乙個引數相對應的。第乙個引數決定了協議層level,第二個引數決定了該協議層下選項組合。sol_socket的選項組合如下:
協議層 選項名字
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
具體的一些組合用法可見:
第三個引數設為1,這裡我也沒很明白其中的意思,我試著把1換成50,結果是一樣的。換成0也是可以的,沒發現什麼區別。希望大牛們給指點一下。
4、s.bind((host,port))繫結主機埠。
5、s.listen(1):listen函式使用主動連線套介面變為被連線套介面,使得乙個程序可以接受其它程序的請求,從而成為乙個伺服器程序。在tcp伺服器程式設計中listen函式把程序變為乙個伺服器,並指定相應的套接字變為被動連線。這裡的引數涉及到一些網路的細節。在程序正理乙個乙個連線請求的時候,可能還存在其它的連線請求。因為tcp連線是乙個過程,所以可能存在一種半連線的狀態,有時由於同時嘗試連線的使用者過多,使得伺服器程序無法快速地完成連線請求。如果這個情況出現了,伺服器程序希望核心如何處理呢?核心會在自己的程序空間裡維護乙個佇列以跟蹤這些完成的連線但伺服器程序還沒有接手處理或正在進行的連線,這樣的乙個佇列核心不可能讓其任意大,所以必須有乙個大小的上限。這個backlog告訴核心使用這個數值作為上限。毫無疑問,伺服器程序不能隨便指定乙個數值,核心有乙個許可的範圍。這個範圍是實現相關的。很難有某種統一,一般這個值會小30以內。這裡設定為1表示每次最多只有乙個等候處理的連線。
6、while迴圈從accept()函式開始。程式會在連線了乙個客戶端後關閉socket。當某個客戶端連線的時,accept返回兩個資訊,乙個新的連線客戶端socket和客戶端的ip位址、埠號。如在上面的例子中新增print語句輸出clientsock和clientaddr,你會發現clientsock為socket.socketobject,clientaddr=('客戶端ip',埠)。後面的迴圈中使用了檔案類物件,伺服器接著顯示出一些介紹性資訊,從客戶端讀乙個字串,顯示乙個應答,最後關閉客戶端socket。
Python網路程式設計 學習筆記
1 為了把全世界的所有不同型別的計算機都連線起來,就必須規定一套全球通用的協議,為了實現網際網路這個目標,網際網路協議簇 internet protocol suite 就是通用協議標準。internet是由inter和net兩個單詞組合起來的,原意就是連線 網路 的網路,有了internet,任何...
學習筆記 Python網路程式設計
tcp程式設計 server 1 import socket,threading,time23 defdealclient sock,addr 4print accept new connection from s s.addr 5 sock.send b hello,i am server 給cl...
c 網路程式設計學習筆記 1
前序 在多個os平台上開發和移植網路應用程式時,將面臨錯綜複雜的挑戰。這些複雜性的表現形式各異 網路協議不相容,在不同軟 硬體平台上具有不同的api和語義的元件庫,os本身的程序間通訊 ipc 機制和併發機制的侷限性造成的 偶發複雜性 直接針對os api程式設計會導致以下兩個問題 1 容易出錯。因...