| 订阅 | 在线投稿
分享
 
 
 

在PHP中使用Sockets:从Usenet中获取文件

2008-12-22 08:09:21 编辑來源:互联网 国际版 评论
 
 
  作者: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/去下载。
 
 
作者:Armel Fauveau 原文地址:[url=http://www.phpbuilder.net/columns/armel20010427.php3]http://www.phpbuilder.net/columns/armel20010427.php3[/url] 译者:许立强[url=mailto:feifengxlq@gmail.com]feifengxlq@gmail.com[/url] [url=http://www.phpobject.net/blog/]Http://www.phpobject.net/blog/[/url] 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()的更多信息可以访问[url=http://www.php.net/manual/function.fsockopen.php]http://www.php.net/manual/function.fsockopen.php[/url] 网络新闻传输协议(NNTP) 访问一个usenet新闻服务器需要用到一个特别的协议,称作NNTP,即网络新闻传输协议标准。这个协议的详细资料在RFC977中,你可以在[url=http://www.w3.org/Protocols/rfc977/rfc977.html]http://www.w3.org/Protocols/rfc977/rfc977.html[/url]中查看到。这个文档详细的描述了如何使用不同的命令来连接并且和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应用程序能进行新闻分组下的关键字搜索。这里有一个例子,你可以访问[url=http://www.phpindex.com/ng/]http://www.phpindex.com/ng/[/url]去下载。
󰈣󰈤
日版宠物情人插曲《Winding Road》歌词

日版宠物情人2017的插曲,很带节奏感,日语的,女生唱的。 最后听见是在第8集的时候女主手割伤了,然后男主用嘴帮她吸了一下,插曲就出来了。 歌手:Def...

兄弟共妻,我成了他们夜里的美食

老钟家的两个儿子很特别,就是跟其他的人不太一样,魔一般的执着。兄弟俩都到了要结婚的年龄了,不管自家老爹怎么磨破嘴皮子,兄弟俩说不娶就不娶,老父母为兄弟两操碎了心...

网络安全治理:国家安全保障的主要方向是打击犯罪,而不是处置和惩罚受害者

来源:中国青年报 新的攻击方法不断涌现,黑客几乎永远占据网络攻击的上风,我们不可能通过技术手段杜绝网络攻击。国家安全保障的主要方向是打击犯罪,而不是处置和惩罚...

 
 
 
>>返回首页<<
 为你推荐
 
 
 
 转载本文
 UBB代码 HTML代码
复制到剪贴板...
 
 
 热帖排行
 
黑色魅力_醉人的美
梦幻蒙眬_如痴如醉
北京的“尖叫”建筑
高天上流云
 
 
王朝网络微信公众号
微信扫码关注本站公众号wangchaonetcn
 
  免责声明:本文仅代表作者个人观点,与王朝网络无关。王朝网络登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
©2005- 王朝网络 版权所有