分享
 
 
 

在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- 王朝網路 版權所有