python網路編程學習筆記(三):socket網路伺服器_python

來源:互聯網
上載者:User

1、TCP串連的建立方法

用戶端在建立一個TCP串連時一般需要兩步,而伺服器的這個過程需要四步,具體見下面的比較。

步驟 TCP用戶端 TCP伺服器
第一步 建立socket對象  建立socket對象
第二步 調用connect()建立一個和伺服器的串連 設定socket選項(可選)
第三步 綁定到一個連接埠(也可以是一個指定的網卡)
第四步 偵聽串連

下面具體來講這四步的建立方法:

第一步,建立socket對象:這裡與用戶端一樣,依然是:

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

第二步,設定和得到socket選項

python定義了setsockopt()和getsockopt(),一個是設定選項,一個是得到設定。這裡主要使用setsockopt(),具體結構如下:

setsockopt(level,optname,value)

level定義了哪個選項將被使用。通常情況下是SOL_SOCKET,意思是正在使用的socket選項。它還可以通過設定一個特殊協議號碼來設定協議選項,然而對於一個給定的作業系統,大多數協議選項都是明確的,所以為了簡便,它們很少用於為行動裝置設計的應用程式。

optname參數提供使用的特殊選項。關於可用選項的設定,會因為作業系統的不同而有少許不同。如果level選定了SOL_SOCKET,那麼一些常用的選項見下表:

選項

意義

期望值

SO_BINDTODEVICE

可以使socket只在某個特殊的網路介面(網卡)有效。也許不能是移動可攜式裝置

一個字串給出裝置的名稱或者一個Null 字元串返回預設值

SO_BROADCAST

允許廣播位址發送和接收資訊包。只對UDP有效。如何發送和接收廣播資訊包

布爾型整數

SO_DONTROUTE

禁止通過路由器和網關往外發送資訊包。這主要是為了安全而用在乙太網路上UDP通訊的一種方法。不管目的地址使用什麼IP地址,都可以防止資料離開本網

布爾型整數

SO_KEEPALIVE

可以使TCP通訊的資訊包保持連續性。這些資訊包可以在沒有資訊傳輸的時候,使通訊的雙方確定串連是保持的

布爾型整數

SO_OOBINLINE

可以把收到的不正常資料看成是正常的資料,也就是說會通過一個標準的對recv()的調用來接收這些資料

布爾型整數

SO_REUSEADDR

當socket關閉後,本地端用於該socket的連接埠號碼立刻就可以被重用。通常來說,只有經過系統定義一段時間後,才能被重用。

布爾型整數



本節在學習時,用到了SO_REUSEADDR選項,具體寫法是:

S.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 這裡value設定為1,表示將SO_REUSEADDR標記為TRUE,作業系統會在伺服器socket被關閉或伺服器處理序終止後馬上釋放該伺服器的連接埠,否則作業系統會保留幾分鐘該連接埠。

下面的方法可以協助給出該系統下python所支援的socket選項列表:

複製代碼 代碼如下:

import socket
solist=[x for x in dir(socket) if x.startswith('SO_')]
solist.sort()
for x in solist:
    Print x

第三步:綁定socket

綁定即為伺服器要求一個連接埠號碼。

S.bind((host,port)),其中host為伺服器ip,通常為空白,也可以綁定到一個特定的ip地址。Port為連接埠號碼。

第四步:偵聽串連。

利用listen()函數進行偵聽串連。該函數只有一個參數,其指明了在伺服器實際處理串連的時候,允許有多少個未決(等待)的串連在隊列中等待。作為一個約定,很多人設定為5。如:s.listen(5)

2、簡單的TCP伺服器執行個體
 
        這個建立一個簡單的TCP伺服器和用戶端。

伺服器端:TCP響應伺服器,當與用戶端建立串連後,伺服器顯示用戶端ip和連接埠,同時將接收的用戶端資訊和'I get it!'傳給用戶端,此時等待輸入一個新的資訊傳給用戶端。

用戶端:TCP用戶端,首先輸入伺服器ip地址,然後輸入資訊,斷行符號後會得到伺服器返回資訊,然後等待伺服器向其發送資訊後退出。

具體代碼如下:
伺服器端:tcpserver.py

複製代碼 代碼如下:

# -*- coding: cp936 -*-
##tcp響應伺服器,當與用戶端建立串連後,伺服器顯示用戶端ip和連接埠,同時將接收的用戶端資訊和'I get it!'傳給用戶端,此時等待輸入一個新的資訊傳給用戶端。
##@小五義
import socket,traceback
host=''
port=12345
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host,port))
s.listen(1)

while 1:
    try:
        clientsock,clientaddr=s.accept()
    except KeyboardInterrupt:
        raise
    except:
        traceback.print_exc()
        continue
    try:
        print "串連來自:",clientsock.getpeername()
        while 1:
            data=clientsock.recv(4096)
            if not len(data):
                break
            print clientsock.getpeername()[0]+':'+str(data)
            clientsock.sendall(data)
            clientsock.sendall("\nI get it!\n")
            t=raw_input('input the word:')
            clientsock.sendall(t)
    except (KeyboardInterrupt,SystemExit):
        raise
    except:
        traceback.print_exc()

    try:
        clientsock.close()
    except KeyboardInterrupt:
        raise
    except:
        traceback.print_exc()

用戶端:tcpclient.py

複製代碼 代碼如下:

# -*- coding: cp936 -*-
##tcp用戶端,首先輸入伺服器ip地址,然後輸入資訊,斷行符號後會得到伺服器返回資訊,然後等待伺服器向其發送資訊後退出。
##@小五義
import socket,sys
port=12345
host=raw_input('輸入伺服器ip:')
data=raw_input('輸入要發送的資訊:')
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
    s.connect((host,port))
except:
    print '串連錯誤!'
s.send(data)
s.shutdown(1)
print '發送完成。'
while 1:
    buf=s.recv(4096)
    if not len(buf):
        break
    sys.stdout.write(buf)

執行結果:

用戶端輸入hello,伺服器端輸入ok,具體顯示結果是:

伺服器端:

串連來自:('127.0.0.1',1945)
127.0.0.1:hello
Input the world:ok
用戶端:
輸入伺服器ip:127.0.0.1
輸入要發送的資訊:hello
發送完成。
hello
I get it!
ok

3、UDP伺服器

UDP伺服器建立與TCP相類似,具體比較如下:

步驟

UDP

TCP

第一步

建立socket對象

建立socket對象

第二步

設定socket選項

設定socket選項

第三步

綁定到一個連接埠

綁定到一個連接埠

第四步

Recvfrom()

偵聽串連listen


這裡利用UDP建立一個時間伺服器。

代碼如下:

伺服器端;serverudp.py

複製代碼 代碼如下:

# -*- coding: cp936 -*-
##UDP伺服器端,用戶端串連後,向其發送目前時間
##@小五義
import socket,traceback,time,struct
host=''
port=12345
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host,port))

while 1:
    try:
        message,address=s.recvfrom(8192)
        secs=int(time.time())
        reply=struct.pack("!I",secs)
        s.sendto(reply,address)
    except (KeyboardInterrupt,SystemExit):
        raise
    except:
        traceback.print_exc()

用戶端:clientudp.py

複製代碼 代碼如下:

# -*- coding: cp936 -*-
##udp用戶端,向伺服器發送一個Null 字元後,得到伺服器返回時間
##@小五義
import socket,sys,struct,time
host=raw_input('輸入伺服器位址:')
port=12345
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.sendto('',(host,port))
print "等待回複……"
buf=s.recvfrom(2048)[0]
if len(buf)!=4:
    print "回複錯誤%d:%s"%(len(buf),buf)
    sys.exit(1)
secs=struct.unpack("!I",buf)[0]
print time.ctime(int(secs))

運行結果:

首先運行伺服器端,然後運行用戶端。
C:\>python clientudp.py  ##clientudp.py程式存放在在c盤下
輸入伺服器位址:127.0.0.1
等待回複……
Mon Aug 06 17:09:17 2012

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.