Perl Socket 編程
Socket又稱"套接字",應用程式通常通過"套接字"向網路發出請求或者應答網路請求,使主機間或者一臺電腦上的進程間可以通訊。
本章節我們為大家接收 Perl 語言中如何使用 Socket 服務。
創建服務端
使用 socket 函數來創建 socket服務。
使用 bind 函數綁定端口。
使用 listen 函數監聽端口。
使用 accept 函數接收客戶端請求。
創建客戶端
使用 socket 函數來創建 socket 服務。
使用 connect 函數連接到 socket 服務端。
以下圖表演示了客戶端與服務端之間的通信流程:
服務端 socket 函數
socket 函數
Perl 中,我們用 socket()函數來創建套接字,語法格式如下:
socket( SOCKET, DOMAIN, TYPE, PROTOCOL );
參數解析:
DOMAIN 創建的套接字指定協議集。 例如:
AF_INET
表示IPv4網路協議AF_INET6
表示IPv6AF_UNIX
表示本地套接字(使用一個檔)
TYPE 套接字類型可以根據是面向連接的還是非連接分為SOCK_STREAM或SOCK_DGRAM
PROTOCOL 應該是 (getprotobyname('tcp'))[2]。指定實際使用的傳輸協議。
所以 socket 函數調用方式如下:
use Socket # 定義了 PF_INET 和 SOCK_STREAM socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2]);
bind() 函數
使用 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_aton($server_ip_address))) or die "無法綁定端口! \n";
or die 在綁定地址失敗後執行。
通過設置 setsockopt() 可選項 SO_REUSEADDR 設置端口可立即重複使用。
pack_sockaddr_in() 函數將地址轉換為二進位格式。
listen() 函數
當socket和一個地址綁定之後,listen()函數會開始監聽可能的連接請求。然而,這只能在有可靠數據流保證的時候使用:
listen( SOCKET, QUEUESIZE );
SOCKET : 一個socket的描述符。
QUEUESIZE : 是 一個決定監聽佇列大小的整數,當有一個連接請求到來,就會進入此監聽佇列;當一個連接請求被accept()接受,則從監聽佇列中移出;當佇列滿後,新的連接請求會返回錯誤。
一旦連接被接受,返回0表示成功,錯誤返回-1。
accept() 函數
accept() 函數接受請求的socket連接。如果成功則返回壓縮形式的網路地址,否則返回FALSE:
accept( NEW_SOCKET, SOCKET );
NEW_SOCKET : 一個socket的描述符。
SOCKET : 一個socket的描述符。
accept() 通常應用在無限迴圈當中:
while(1) { accept( NEW_SOCKET, SOCKT ); ....... }
以上實例可以即時監聽客戶端的請求。
客戶端函數
connect() 函數
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 我是來自服務端的資訊