1.Socket
socket也稱作“套接字”,用于描述IP位址和端口,是一個通信鍊的句柄。應用程式通常通過“套接字”向網絡送出請求或者應答網絡請求。可以列舉中國移動或者是中國電信等的電話客服,當然,也可以看下面的圖檔來作形象的說明。
socket起源于Unix,而Unix/Linux基本哲學之一就是:一切皆檔案,即都可以用“打開open—>讀寫write/read—>關閉close”模式來操作。Socket就是該模式的一個實作,socket即是一種特殊的檔案,一些socket函數就是對其進行的操作(讀/寫IO、打開、關閉)。
可以看下面的圖示來形象說明:
<a href="http://s3.51cto.com/wyfs02/M02/74/07/wKioL1YPYV-ASBXxAAG4ZzVVxxg286.jpg" target="_blank"></a>
2.Socket程式設計
(1)Socket伺服器程式設計
主要包括下面的幾步:
1.打開socket
2.綁定到一個位址和端口
3.偵聽進來的連接配接
4.接受連接配接
5.讀寫資料
(2)Socket用戶端程式設計
2.連接配接到一個位址和端口
3.讀寫資料
3.Socket類型
Socket從類型上分,可以有以下幾種:
socket類型
适用範圍
說明
socket.AF_UNIX
隻能夠用于單一的Unix系統程序間通信
不能在不同主機之間通信
socket.AF_INET
伺服器之間網絡通信
目前常用的就是這種
socket.AF_INET6
IPv6
由于IPv6未推廣,也少用
上面是socket的類型,細分的話還有socket的資料包類型,圖示如下:
<a href="http://s3.51cto.com/wyfs02/M00/74/09/wKiom1YPZeHgW_wqAAHUjUnzsUk309.jpg" target="_blank"></a>
常用的是第一種和第二種,即for TCP和for UDP的類型,當然socket.SOCK_RAW也需要注意,因為它可以構造IP頭,是以沿着這個思路,可以合僞造不同源IP位址的資料包,以對一些中小型企業伺服器發動Dos攻擊。
4.Socket函數
對socket進行相關操作如“讀/寫IO、打開、關閉”的函數即是Socket函數,可以看下面的圖示:
5.Socket例子
下面就寫一個單線程非互動式的socket,在本機裡實作通信就好了。
Server端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<code>import</code> <code>socket #導入socket類</code>
<code>HOST =</code><code>''</code> <code>#定義偵聽本地位址口(多個IP位址情況下),這裡表示偵聽所有,也可以寫成</code><code>0.0</code><code>.</code><code>0.0</code>
<code>PORT = </code><code>50007</code> <code>#Server端開放的服務端口</code>
<code>s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #選擇Socket類型和Socket資料包類型</code>
<code>s.bind((HOST, PORT)) #綁定IP位址和端口</code>
<code>s.listen(</code><code>1</code><code>) #定義偵聽數開始偵聽(實際上并沒有效果)</code>
<code>conn, addr = s.accept() #定義執行個體,accept()函數的傳回值可以看上面的socket函數說明</code>
<code>print </code><code>'Connected by'</code><code>, addr</code>
<code>while</code> <code>1</code><code>:</code>
<code> </code><code>data = conn.recv(</code><code>1024</code><code>) #接受套接字的資料</code>
<code> </code><code>if</code> <code>not data:</code><code>break</code> <code>#如果沒有資料接收,則斷開連接配接</code>
<code> </code><code>print </code><code>'revc:'</code><code>,data #發送接收到的資料</code>
<code> </code><code>conn.sendall(data) #發送接收到的資料</code>
<code>conn.close() #關閉套接字</code>
Client端:
<code>import</code> <code>socket</code>
<code>HOST = </code><code>'192.168.1.13'</code> <code>#定義目标主機名</code>
<code>PORT = </code><code>50007</code> <code>#定義目标主機開放服務端口号</code>
<code>s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #選擇Socket類型和Socket資料包類型 </code>
<code>s.connect((HOST, PORT)) #連接配接到目标主機的socket(套接字)中</code>
<code>s.sendall(</code><code>'Hello, world!'</code><code>) #發送資料</code>
<code>data = s.recv(</code><code>1024</code><code>) #接收資料</code>
<code>s.close() #關閉socket</code>
<code>print </code><code>'Received'</code><code>, repr(data)</code>
示範:
步驟1:Server端運作服務端程式
<code>xpleaf@xpleaf-machine:/mnt/hgfs/Python/day5$ python server4.py </code>
<code>===>光标在此處處于等待狀态</code>
步驟2:Client端運作用戶端程式
<code>xpleaf@xpleaf-machine:/mnt/hgfs/Python/day5$ python client4.py </code>
<code>Received 'Hello, world! ===>收到服務端傳回的資料</code>
步驟3:在Server端中觀察現象
<code>Connected by (</code><code>'192.168.1.13'</code><code>, </code><code>52641</code><code>) ===>有用戶端連接配接進來,</code><code>52641</code><code>為Client的随機端口号</code>
<code>revc: Hello, world! ===>收到來自Client端的資料</code>
本文轉自 xpleaf 51CTO部落格,原文連結:http://blog.51cto.com/xpleaf/1700032,如需轉載請自行聯系原作者