如果你是windows請(qǐng)通過ppm安裝IO::Socket包,如果你是linux系統(tǒng),請(qǐng)通過cpanm Module::Name來安裝IO::Socket包,然后在程序中添加use IO::Socket;
IO::Socket下又有兩個(gè)子類IO::Socket::INET與IO::Socket::UNIX,我們現(xiàn)在使用IO::Socket::INET。
作為一個(gè)簡(jiǎn)單的客戶端,它的步驟只需要先調(diào)用new方法,然后立刻就可以進(jìn)行基本I/O操作了,最后只需調(diào)用close方法結(jié)束會(huì)話,那么整個(gè)SOCKET會(huì)話就算完成了。
new()方法:
SOCKET對(duì)象變量=IO::Socket::INET->new(SOCKET變量值);
實(shí)例:
講解:
所有的PERL對(duì)象編程都把對(duì)象'形象化’為某個(gè)變量,這里的SOCKET句柄對(duì)象也不例外,調(diào)用此方法的返回值便為SOCKET對(duì)象變量了。這里使用參數(shù)為簡(jiǎn)單參數(shù)模式,在雙引號(hào)或但引號(hào)內(nèi)的socket地址結(jié)構(gòu)為'主機(jī)IP或域名:端口號(hào)或服務(wù)名稱',也可以是'主機(jī)IP或域名:服務(wù)名稱(端口號(hào))'。除了最簡(jiǎn)單的單參數(shù)調(diào)用外,new方法還有很多參數(shù)可以選擇性調(diào)用的,下面就對(duì)這些參數(shù)作出一個(gè)簡(jiǎn)單的概括吧:
參數(shù)PeerAddr(遠(yuǎn)程主機(jī)地址)與PeerHost(遠(yuǎn)程主機(jī)名)基本相同,調(diào)用方式也相同,其值格式除了標(biāo)準(zhǔn)的格式外,還可以加':'號(hào)后再加端口或服務(wù),這樣的的話,后面的參數(shù)PeerPort(遠(yuǎn)程主機(jī)端口或服務(wù))的值就無效了。
參數(shù)PeerPort(遠(yuǎn)程主機(jī)端口或服務(wù)),其值的格式可以是端口,還可以是服務(wù)名,更可以是'組合’,如:"telnet(23)";當(dāng)PeerAddr(遠(yuǎn)程主機(jī)地址)或PeerHost(遠(yuǎn)程主機(jī)名)的值格式中指明了端口,再調(diào)用此參數(shù)時(shí),此參數(shù)的值無效。
參數(shù)LocalAddr(本地主機(jī)地址)、LocalHost(本地主機(jī)名)、LocalPort(本地主機(jī)端口或服務(wù))之間的關(guān)系與調(diào)用方式與上面介紹的三個(gè)參數(shù)PeerAddr(遠(yuǎn)程主機(jī)地址)、PeerHost(遠(yuǎn)程主機(jī)名)、PeerPort(遠(yuǎn)程主機(jī)端口或服務(wù))相當(dāng)。
還有一種情況,就是如果只定義了LocalPort(本地主機(jī)端口或服務(wù)),而沒有定義LocalAddr(本地主機(jī)地址)或LocalHost(本地主機(jī)名),那IO::Socket會(huì)將本地機(jī)器的地址的值默認(rèn)為INADDR_ANY通配符,也就是不定義本地主機(jī)的地址值的話就定義為允許所有接口。
Proto(協(xié)議類型)的值可以用兩種方式表示。一種是直接的字符串表示方式,如:proto=>"tcp"表示該協(xié)議類型為TCP。第二種方式就是直接使用協(xié)議號(hào)了,EGP---8、HMP---20、ICMP---1、RAW---255、RDP---27、RVD---66、TCP---6、UDP---17、XNS-IDP---22、其他---22、ALL---0;也可以使用getprotobyname函數(shù)加協(xié)議名為參數(shù)調(diào)用獲的該值,如:proto=>getprotobyname('tcp')。該形式也表示該協(xié)議的類型為TCP。建議還是使用第一種方式比較方便。
Type(套接字類型)的值通常為SOCK_STREAM(流套接字)、SOCK_DGRAM(數(shù)據(jù)報(bào)套接字)、SOCK_RAW(原始套接字)等,不用說大家都知道,TCP用的是流套接字,UDP用的是數(shù)據(jù)報(bào)套接字,構(gòu)造IP包用的是原始套接字。
如果上面的參數(shù)Proto(協(xié)議類型)與Type(套接字類型)的值都不定義的話,IO::Socket::INET就會(huì)通過程序中上下'文’部分猜估它們的值,猜估不到的話就會(huì)默認(rèn)為'tcp'。
參數(shù)Listen(監(jiān)聽隊(duì)列的長(zhǎng)度)的值是一個(gè)整形數(shù)。它代表能接受的連接主機(jī)數(shù)量。如果您要構(gòu)造服務(wù)端的話,Listen這個(gè)步驟是必不可少的。
調(diào)用Reuse(在綁定前設(shè)置SO_REUSEADDR)可以免去服務(wù)器在終止到重啟之間的所停留的時(shí)間。
Timeout(超時(shí)值)以秒計(jì)算,用于連接中的connect與accept這兩個(gè)步驟,調(diào)用目的是為了在連接遠(yuǎn)程主機(jī)不可到達(dá)時(shí)限制連接的掛起時(shí)間。
MultiHomed(用于連接多IP地址)的值是一個(gè)布爾值,當(dāng)其值為真時(shí),如果要連接的主機(jī)擁有多個(gè)IP地址,則本機(jī)的new方法調(diào)用gethostbyname()窮舉其所有IP地址,直到能成功調(diào)用為止。
從樓上的列表中可以看到IO::Socket與傳統(tǒng)C庫(kù)的Socket API接口在調(diào)用上有什么不同了:
1)控制范圍不同。C庫(kù)提供的接口在生成SOCKET句柄時(shí)只能控制的只有域、套接字類型、協(xié)議這幾個(gè)參數(shù)。而IO::Socket接口的創(chuàng)建語句(調(diào)用new方法)幾乎能決定這個(gè)套接字的所有參數(shù)。
2)調(diào)用所使用的'協(xié)議’定義部分不同。IO::Socket接口調(diào)用new方法中的參數(shù)'Proto'的值可以直接定義為'tcp',這比傳統(tǒng)C庫(kù)的Socket定義更為簡(jiǎn)便。
3)IO::Socket在定義時(shí)能直接定義本地主機(jī)地址、本地端口與遠(yuǎn)程主機(jī)地址、遠(yuǎn)程端口在一個(gè)Socket中,如果是這種情況的服務(wù)端就無需調(diào)用accept了,在I/O讀寫部分可以直接向這個(gè)Socket進(jìn)行讀寫操作,而無需再定義遠(yuǎn)程客戶端的Socket了。
accept()方法:
遠(yuǎn)程連接套接字對(duì)象變量=服務(wù)端套接字對(duì)象變量>accept();
實(shí)例:
講解:
此方法的調(diào)用環(huán)境與傳統(tǒng)C中SOCKET庫(kù)調(diào)用原理一樣,用于服務(wù)端的等待監(jiān)聽過程。無參數(shù),返回值為遠(yuǎn)程連接的套接字對(duì)象變量。調(diào)用此方法也是一個(gè)生成套接字的過程,只不過此套接字為遠(yuǎn)程連接的套接字而已,它以對(duì)象變量方式存在,據(jù)有與本地套接字變量相同的屬性與方法。
accept()方法在IO::Socket包里還提供另一種雙返回值的調(diào)用方法:
(遠(yuǎn)程連接套接字對(duì)象變量,遠(yuǎn)程主機(jī)壓縮地址變量)=服務(wù)端對(duì)象變量->accept();
實(shí)例:
講解:
與樓上一個(gè)返回值的調(diào)用方式基本相同,只是返回值中多了一個(gè)變量而已,返回值中多了個(gè)變量------遠(yuǎn)程主機(jī)壓縮地址變量。
bind()方法:
返回值變量=服務(wù)端套接字對(duì)象變量->bind(本地端口號(hào),本地主機(jī)網(wǎng)絡(luò)地址);
實(shí)例:
講解:
bind方法用于在服務(wù)器端綁定主機(jī)的地址與端口。它使用的兩個(gè)參數(shù)都為未壓縮值,第一個(gè)為端口,第二個(gè)為主機(jī)的網(wǎng)絡(luò)適配器接口地址(可以使用默認(rèn)的保留字INADDR_ANY,此保留字包括了主機(jī)的所有網(wǎng)絡(luò)適配器接口地址,調(diào)用它時(shí),它會(huì)以窮舉的方法窮舉所有的網(wǎng)絡(luò)適配器接口地址,直到找到為止);返回值為布爾值,用于檢測(cè)這次調(diào)用是否成功。
connect()方法:
返回值變量=套接字對(duì)象變量->connect(壓縮地址變量);
實(shí)例:
講解:
常用于TCP連接(也可用于UDP,不過不常用),調(diào)用將向遠(yuǎn)程主機(jī)發(fā)送連接請(qǐng)求。參數(shù)'壓縮地址變量’為sockaddr_in形式值,返回值為布爾值。若調(diào)用此方法則建立IO::Socket::INET對(duì)象時(shí)不能賦予參數(shù)'PeerAddr'或'PeerHost'、'PeerPort',否則就會(huì)出現(xiàn)程序邏輯錯(cuò)誤。
connect()方法也有雙參數(shù)調(diào)用方式,使用起來更簡(jiǎn)單:
返回值變量=套接字對(duì)象變量->connect(遠(yuǎn)程端口號(hào),遠(yuǎn)程主機(jī)地址);
實(shí)例:
講解:
調(diào)用的目的與樓上單參數(shù)的調(diào)用方式相當(dāng)。第一個(gè)參數(shù)為遠(yuǎn)程需要連接的主機(jī)的端口(等于new方法的參數(shù)'PeerPort'),第二個(gè)參數(shù)為需要連接的主機(jī)地址(等于new方法的參數(shù)'PeerAddr'或'PeerHost'),返回值為布爾值。
listen()方法:
返回值變量=套接字對(duì)象變量->listen(請(qǐng)求隊(duì)列的最大長(zhǎng)度值);
實(shí)例:
講解:
TCP服務(wù)端不可缺少的方法。單參數(shù),參數(shù)為此服務(wù)端接受遠(yuǎn)端請(qǐng)求隊(duì)列的最大長(zhǎng)度值,返回值為布爾值。調(diào)用此方法等同于在建立IO::Socket::INET對(duì)象時(shí)定義參數(shù)'Listen'的值,所以若在new方法中定義了參數(shù)'Listen'再調(diào)用此方法的話就會(huì)出現(xiàn)'程序定義沖突’這樣的邏輯錯(cuò)誤了。
shutdown()方法:
返回值變量=套接字對(duì)象變量->shutdown(控制參數(shù));
實(shí)例:
講解:
此方法是除了close外的另一個(gè)關(guān)閉套接字對(duì)象的方法。單參數(shù),參數(shù)值為外加參數(shù)定義,下為此方法的外加參數(shù)列表:
其返回值為布爾值。
send()方法:
成功發(fā)送的數(shù)據(jù)值變量=套接字對(duì)象變量->send(發(fā)送數(shù)據(jù),標(biāo)志值,目標(biāo)地址值);
實(shí)例:
講解:
send方法是專門為SOCKET發(fā)送數(shù)據(jù)的特殊方法,調(diào)用格式與參數(shù)格式也基本與C庫(kù)的SOCKET API中的send函數(shù)相同。第一個(gè)參數(shù)是需要發(fā)送的數(shù)據(jù);第二參數(shù)是標(biāo)志值,不添的話默認(rèn)為0;第三個(gè)參數(shù)通常只用于UDP連接,是需要連接的sockaddr_in格式地址值(注意:當(dāng)?shù)谌齻€(gè)參數(shù)有必要一定要寫時(shí),第二個(gè)參數(shù)也一定要加上);返回值為成功發(fā)送的數(shù)據(jù)值大小(以byte為單位)。
recv()方法:
壓縮遠(yuǎn)程地址地址=套接字對(duì)象變量->recv(接收數(shù)據(jù)變量,接收數(shù)據(jù)值長(zhǎng)度,標(biāo)志值);
實(shí)例:
講解:
recv方法是專門為SOCKET接收數(shù)據(jù)的特殊方法,調(diào)用格式與參數(shù)格式也與C庫(kù)的SOCKET API基本一樣。第一個(gè)參數(shù)是存放接收后的數(shù)據(jù)的變量值;第二個(gè)參數(shù)是接收的數(shù)據(jù)的長(zhǎng)度值;第三個(gè)參數(shù)是標(biāo)志值,默認(rèn)為0就可以了(省略此值不填,系統(tǒng)默認(rèn)也為0)。
聯(lián)系客服