Socket又稱"套接字",應用程式通常透過"套接字"向網路發出請求或應答網路請求,使主機間或一台電腦上的進程間可以通訊。
本章節我們為大家接收Perl 語言如何使用Socket 服務。
使用socket函數來建立socket服務。
使用bind函數綁定連接埠。
使用listen函數監聽連接埠。
使用accept函數接收客戶端請求。
使用socket函數來建立socket 服務。
使用connect函數連接到socket 服務端。
以下圖表示範了客戶與服務端之間的通訊流程:
Perl 中,我們用socket()函數來建立套接字,語法格式如下:
socket( SOCKET, DOMAIN, TYPE, PROTOCOL );
參數解析:
DOMAIN所建立的套接字指定協定集。 例如:
AF_INET
表示IPv4網路協定
AF_INET6
表示IPv6
AF_UNIX
表示本機套接字(使用一個檔案)
TYPE套接字類型可以根據是面向連線的還是非連線分為SOCK_STREAM或SOCK_DGRAM
PROTOCOL應該是(getprotobyname('tcp'))[2] 。指定實際使用的傳輸協定。
所以socket 函數呼叫方式如下:
use Socket # 定義了PF_INET 和SOCK_STREAMsocket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2]);
使用bind() 為套接字指派一個位址:
bind( SOCKET, ADDRESS );
SOCKET 一個socket的描述子。 ADDRESS 是socket 位址( TCP/IP ) 包含了三個元素:
位址簇(TCP/IP, 是AF_INET, 在你係統上可能是2)
連接埠號碼(例如21)
網路位址(例如10.12.12.168)
使用socket()建立套接字後,只賦予其所使用的協議,並未分配位址。在接受其它主機的連線前,必須先呼叫bind()為套接字分配一個位址。
簡單實例如下:
use Socket # 定義了PF_INET 和SOCK_STREAM$port = 12345; # 監聽的連接埠$server_ip_address = "10.12.12.168";bind( SOCKET, pack_sockaddr_in($port, inet_aa($server_cton)($server_cdie) " n";
or die在綁定位址失敗後執行。
透過設定setsockopt() 可選項SO_REUSEADDR 設定連接埠可立即重複使用。
pack_sockaddr_in()函數將位址轉換為二進位格式。
當socket和一個位址綁定之後,listen()函數會開始監聽可能的連線請求。然而,這只能在有可靠資料流保證的時候使用:
listen( SOCKET, QUEUESIZE );
SOCKET : 一個socket的描述子。
QUEUESIZE : 是一個決定監聽佇列大小的整數,當有一個連接請求到來,就會進入此監聽佇列;當一個連接請求被accept()接受,則從監聽佇列中移出;當佇列滿後,新的連接請求會回傳錯誤。
一旦連線被接受,返回0表示成功,錯誤返回-1。
accept() 函數接受請求的socket連線。如果成功則傳回壓縮形式的網路位址,否則回傳FALSE:
accept( NEW_SOCKET, SOCKET );
NEW_SOCKET : 一個socket的描述符。
SOCKET : 一個socket的描述子。
accept() 通常應用在無限迴圈當中:
while(1) { accept( NEW_SOCKET, SOCKT ); .......}
以上實例可以即時監聽客戶端的請求。
connect()系統呼叫為一個套接字設定連接,參數有檔案描述符和主機位址。
connect( SOCKET, ADDRESS );
以下建立一個連接到服務端socket 的實例:
$port = 21; # ftp 連接埠$server_ip_address = "10.12.12.168";connect( SOCKET, pack_sockaddr_in($port, inet_aton($server_ip_address))) or die "無法綁定連接埠! n";
接下來我們透過一個完整實例來了解下所有socket 函數的應用:
服務端server.pl 程式碼:
打開一個終端,執行以下程式碼:
$ perl sever.pl訪問啟動:7890
客戶端client.pl 程式碼:
打開另外一個終端,執行以下程式碼:
$ perl client.pl我是來自服務端的信息