分享
 
 
 

在PHP中使用Sockets:從Usenet中獲取文件

王朝php·作者佚名  2008-12-22
窄屏简体版  字體: |||超大  

作者:Armel Fauveau

原文地址:http://www.phpbuilder.net/columns/armel20010427.php3

譯者:許立強feifengxlq@gmail.com

Http://www.phpobject.net/blog/

PHP能夠打開遠程或者本地服務器的sockets!這裏是一個使用socket的簡單的例子:連接到Usenet的新聞服務器,與服務器溝通,並從一個精確的新聞分組中下載一些文章。

使用PHP打開Socket

使用fsockopen()來打開一個Socket。這個函數在PHP3和PHP4中都存在。函數的原型如下:

<?php

intfsockopen

(string hostname,

int port[,

int errno[,

string errstr[,

double timeout]]])

?>

對於網絡主機,它將建立一個TCP的Socket的連接到主機名的端口上。主機名可以是域名或者IP地址。對於UDP連接,你需要明確指出其協議:udp://hostname。對於unix主機,主機名將在socket的路徑中使用,在這個例子中端口必須設置成0。可選項timeout可以用來設置連接超時的秒數。

關於fsockopen()的更多信息可以訪問http://www.php.net/manual/function.fsockopen.php

網絡新聞傳輸協議(NNTP)

訪問一個usenet新聞服務器需要用到一個特別的協議,稱作NNTP,即網絡新聞傳輸協議標準。這個協議的詳細資料在RFC977中,你可以在http://www.w3.org/Protocols/rfc977/rfc977.html中查看到。這個文檔詳細的描述了如何使用不同的命令來連接並且和NNTP服務器對話。

連接服務器

連接到NNTP服務器需要知道服務器的主機名(或者IP地址)和它將要監聽的端口。另外建議你加上一個超時的時間,這樣連接失敗的時候就不會「凍結」程序。

<?php

$cfgServer ="your.news.host";

$cfgPort =119;

$cfgTimeOut =10;

// open asocket

if(!$cfgTimeOut)

// without timeout

$usenet_handle=fsockopen($cfgServer,$cfgPort);

else

// with timeout

$usenet_handle=fsockopen($cfgServer,$cfgPort, &$errno, &$errstr,$cfgTimeOut);

if(!$usenet_handle) {

echo"Connexionfailed\n";

exit();

}

else {

echo"Connected\n";

$tmp=fgets($usenet_handle,1024);

}

?>

與服務器交互

現在我們已經連接上服務器了,而且能夠通過先前打開的socket連接與服務器進行交互。讓我們對服務器說「我們要從某一新聞分組中獲取到最新的10篇文章」。RFC977定義了如何選擇正確的新聞分組的命令,如下:

GROUPggg

必需的參數ggg是你將要選擇的新聞分組的名字,比如net.news。使用list命令你可以獲取到一組有效的新聞列表。成功選擇響應會返回組中首尾兩篇新聞的新聞號以及對存檔新聞號估計。

比如

chrome:~$ telnetmy.news.host 119

Trying aa.bb.cc.dd...

Connected tomy.news.host.

Escape character is'^]'.

200 my.news.hostInterNetNews NNRP server INN 2.2.2 13-Dec-1999 ready (posting ok).

GROUP alt.test

211 232 222996 223235alt.test

quit

205 .

在接受到命令「GROUP alt.test」,新聞服務器返回了「211232 222996 223235 alt.test」。其中211是RFC標識碼(簡單的解釋說命令已經成功的執行—查看RFC你可以獲取更加詳細的資料),返回信息說明其中有232篇文章,其中最舊的新聞的索引號是222996,而最新的新聞索引號是223235。現在讓我們計算下:222996+232並不等於232235。這丟失的文章或者從這服務器移除出去了,或者被他的作者取消了(是的,這是可能的,也是很容易實現的),或者是刪除了。

小心起見,在選擇新聞分組之前,服務器可能需要認證,當然這是由服務器是否公開或者私有來決定的。一般是允許任何人獲取新聞,但發表新聞需要通過認證。

<?php

//$cfgUser = "xxxxxx";

//$cfgPasswd = "yyyyyy";

$cfgNewsGroup ="alt.php";

// identification required on private server

if($cfgUser) {

fputs($usenet_handle,"AUTHINFO USER".$cfgUser."\n");

$tmp=fgets($usenet_handle,1024);

fputs($usenet_handle,"AUTHINFOPASS".$cfgPasswd."\n");

$tmp=fgets($usenet_handle,1024);

// check error

if($tmp!="281Ok\r\n") {

echo"502Authentication error\n";

exit();

}

}

// select newsgroup

fputs($usenet_handle,"GROUP ".$cfgNewsGroup."\n");

$tmp=fgets($usenet_handle,1024);

if($tmp=="480 Authentication required for command\r\n") {

echo"$tmp\n";

exit();

}

$info=split(" ",$tmp);

$first=$info[2];

$last=$info[3];

print"First : $first\n";

print"Last : $last\n";

?>

獲取一些文章

現在我們已經有最新文章的A索引號,那就能很容易的獲取最新的十篇文章。RFC977指出使用ARTICLE命令可以和文章的索引號或者消息的ID一起使用。為了小心起見,在這裏,文章的索引號和消息ID是不同的,因為每個新聞服務器定義不同,所以在不同的新聞服務器上相同文章的索引號都會不一樣的,但是消息ID好是唯一的(包含在文章的頭部中)

<?php

$cfgLimit =10;

// upload last articles

$boucle=$last-$cfgLimit;

while ($boucle<=$last) {

set_time_limit(0);

fputs($usenet_handle,"ARTICLE$boucle\n");

$article="";

$tmp=fgets($usenet_handle,4096);

if(substr($tmp,0,3) !="220") {

echo"+----------------------+\n";

echo"Error onarticle $boucle\n";

echo"+----------------------+\n";

}

else {

while($tmp!=".\r\n") {

$tmp=fgets($usenet_handle,4096);

$article=$article.$tmp;

}

echo"+----------------------+\n";

echo"Article$boucle\n";

echo"+----------------------+\n";

echo"$article\n";

}

$boucle++;

}

?>

我們僅僅從這個服務器的這個分組上獲取了十條最新的新聞。你也可以使用HEAD命令來至獲取文章的頭部信息,或者使用BODY命令來獲取新聞的正文。

關閉連接

使用fclose()函數你就可以結束與NNTP服務器之間的會話,當然你可以些一個新的文件,如下:

<?php

// close connexion

fclose($usenet_handle);

?>

更多關於fclose()的信息,請看:http://www.php.net/manual/function.fclose.php

結論

本文中,我們只說明了在確定的情況下如何打開、使用和關閉一個socket連接:連接上一個NNTP服務器然後從新聞分組中取回一些文章。使用POST命令在NNTP服務器上發表一篇文章並不復雜多少。

因此,下一步就是編寫一個新聞客戶端(並去掉一些Netscape),它需要能很容易的保存文章,並使用一些搜索引擎(比如htgid,http://www.htdig.org/)來索引這些文章,而且要有一個WEB應用程序能進行新聞分組下的關鍵字搜索。這裏有一個例子,你可以訪問http://www.phpindex.com/ng/去下載。

 
 
 
免責聲明:本文為網絡用戶發布,其觀點僅代表作者個人觀點,與本站無關,本站僅提供信息存儲服務。文中陳述內容未經本站證實,其真實性、完整性、及時性本站不作任何保證或承諾,請讀者僅作參考,並請自行核實相關內容。
2023年上半年GDP全球前十五強
 百态   2023-10-24
美眾議院議長啟動對拜登的彈劾調查
 百态   2023-09-13
上海、濟南、武漢等多地出現不明墜落物
 探索   2023-09-06
印度或要將國名改為「巴拉特」
 百态   2023-09-06
男子為女友送行,買票不登機被捕
 百态   2023-08-20
手機地震預警功能怎麽開?
 干货   2023-08-06
女子4年賣2套房花700多萬做美容:不但沒變美臉,面部還出現變形
 百态   2023-08-04
住戶一樓被水淹 還衝來8頭豬
 百态   2023-07-31
女子體內爬出大量瓜子狀活蟲
 百态   2023-07-25
地球連續35年收到神秘規律性信號,網友:不要回答!
 探索   2023-07-21
全球鎵價格本周大漲27%
 探索   2023-07-09
錢都流向了那些不缺錢的人,苦都留給了能吃苦的人
 探索   2023-07-02
倩女手遊刀客魅者強控制(強混亂強眩暈強睡眠)和對應控制抗性的關系
 百态   2020-08-20
美國5月9日最新疫情:美國確診人數突破131萬
 百态   2020-05-09
荷蘭政府宣布將集體辭職
 干货   2020-04-30
倩女幽魂手遊師徒任務情義春秋猜成語答案逍遙觀:鵬程萬裏
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案神機營:射石飲羽
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案昆侖山:拔刀相助
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案天工閣:鬼斧神工
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案絲路古道:單槍匹馬
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案鎮郊荒野:與虎謀皮
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案鎮郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案鎮郊荒野:指鹿為馬
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案金陵:小鳥依人
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案金陵:千金買鄰
 干货   2019-11-12
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有