【Python之旅】第五篇(一):Python Socket通信原理
摘要: 只要和網絡服務涉及的,就離不開Socket以及Socket編程,下面就說說Python Socket通信的基本原理。 1.Socket socket也稱作“套接字”,用於描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過“套接字”向網絡發出請求或者應答網絡請求。可以列舉中國移動或...
只要和網絡服務涉及的,就離不開Socket以及Socket編程,下面就說說Python Socket通信的基本原理。
1.Socket
socket也稱作“套接字”,用於描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過“套接字”向網絡發出請求或者應答網絡請求。可以列舉中國移動或者是中國電信等的電話客服,當然,也可以看下面的圖片來作形象的說明。
socket起源於Unix,而Unix/Linux基本哲學之一就是:一切皆文件,即都可以用“打開open—>讀寫write/read—>關閉close”模式來操作。Socket就是該模式的一個實現,socket即是一種特殊的文件,一些socket函數就是對其進行的操作(讀/寫IO、打開、關閉)。
可以看下面的圖示來形象說明:
2.Socket編程
(1)Socket服務器編程
主要包括下面的幾步:
1.打開socket
2.綁定到一個地址和端口
3.偵聽進來的連接
4.接受連接
5.讀寫數據
(2)Socket客戶端編程
主要包括下面的幾步:
1.打開socket
2.連接到一個地址和端口
3.讀寫數據
3.Socket類型
Socket從類型上分,可以有以下幾種:
socket類型 | 適用范圍 | 說明 |
socket.AF_UNIX | 只能夠用於單一的Unix系統進程間通信 | 不能在不同主機之間通信 |
socket.AF_INET | 服務器之間網絡通信 | 目前常用的就是這種 |
socket.AF_INET6 | IPv6 | 由於IPv6未推廣,也少用 |
上面是socket的類型,細分的話還有socket的數據包類型,圖示如下:
常用的是第一種和第二種,即for TCP和for UDP的類型,當然socket.SOCK_RAW也需要注意,因為它可以構造IP頭,因此沿着這個思路,可以合偽造不同源IP地址的數據包,以對一些中小型企業服務器發動Dos攻擊。
4.Socket函數
對socket進行相關操作如“讀/寫IO、打開、關閉”的函數即是Socket函數,可以看下面的圖示:
只需要記住常用的就可以,即通常會在Server端和Client端中編程會用到的,可以見下面的例子。
5.Socket例子
下面就寫一個單線程非交互式的socket,在本機里實現通信就好了。
Server端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import
socket #導入socket類
HOST =
''
#定義偵聽本地地址口(多個IP地址情況下),這里表示偵聽所有,也可以寫成
0.0
.
0.0
PORT =
50007
#Server端開放的服務端口
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #選擇Socket類型和Socket數據包類型
s.bind((HOST, PORT)) #綁定IP地址和端口
s.listen(
1
) #定義偵聽數開始偵聽(實際上並沒有效果)
conn, addr = s.accept() #定義實例,accept()函數的返回值可以看上面的socket函數說明
print
'Connected by'
, addr
while
1
:
data = conn.recv(
1024
) #接受套接字的數據
if
not data:
break
#如果沒有數據接收,則斷開連接
print
'revc:'
,data #發送接收到的數據
conn.sendall(data) #發送接收到的數據
conn.close() #關閉套接字
|
Client端:
1
2
3
4
5
6
7
8
9
10
11
|
import
socket
HOST =
'192.168.1.13'
#定義目標主機名
PORT =
50007
#定義目標主機開放服務端口號
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #選擇Socket類型和Socket數據包類型
s.connect((HOST, PORT)) #連接到目標主機的socket(套接字)中
s.sendall(
'Hello, world!'
) #發送數據
data = s.recv(
1024
) #接收數據
s.close() #關閉socket
print
'Received'
, repr(data)
|
演示:
步驟1:Server端運行服務端程序
1
2
|
xpleaf@xpleaf-machine:/mnt/hgfs/Python/day5$ python server4.py
===>光標在此處處於等待狀態
|
步驟2:Client端運行客戶端程序
1
2
|
xpleaf@xpleaf-machine:/mnt/hgfs/Python/day5$ python client4.py
Received 'Hello, world! ===>收到服務端返回的數據
|
步驟3:在Server端中觀察現象
1
2
3
|
xpleaf@xpleaf-machine:/mnt/hgfs/Python/day5$ python server4.py
Connected by (
'192.168.1.13'
,
52641
) ===>有客戶端連接進來,
52641
為Client的隨機端口號
revc: Hello, world! ===>收到來自Client端的數據
|