在php中使用sockets:从新闻组中获取文章


Posted in PHP onOctober 09, 2006

PHP能打开远程或本地主机上的Socket端口。本文是一个使用Socket的小例子:连接到一个Usenet新闻组服务器,同服务器对话,从新闻组中下载一些文章。

在php中打开一个socket
使用fsockopen()打开一个socket.这个函数在php3和php4种都可以使用。函数声明是这样的:

int fsockopen (string hostname, int port _
[, int errno [, string errstr [, double timeout]]])

 
这个函数将打开一个连接到主机hostname的port端口的TCP连接。hostname可以是一个有效的域名,或者是一个ip地址。对于udp连接,你必须指定协议:udp://hostname. 对于unix域,主机名使用到socket的路径,这种情况下,端口port必须置为0。可选的timeout参数用来设定等待打开一个socket的时间,单位为秒。

关于fsockopen()的更多信息,请参考:http://www.php.net/manual/function.fsockopen.php

网络新闻传输协议
   访问新闻组服务器需要通过称为NNTP(网络新闻传输协议)的协议来进行。这个协议在rfc977中有详细的细节,可以在http://www.w3.org/Protocols/rfc977/rfc977.html得到。这个文档分别描述了怎样连接到NNTP服务器,怎样同服务器对话,以及完成这些任务的不同命令。

连接
   连接到一个NNTP服务器需要知道它的主机名(或者是ip地址)和它侦听的端口。为了避免一个连接企图失败导致程序挂起,你应该使用timeout参数。
    <?php
      $cfgServer   = "your.news.host";
      $cfgPort     = 119;
      $cfgTimeOut  = 10;

      //open a socket
      if(!$cfgTimeOut)
         // without timeout
         $usenet_handle = fsockopen($cfgServer, $cfgPort);
      else
         // with timeout
         $usenet_handle = fsockopen($cfgServer, $cfgPort, &$errno, &$errstr, $cfgTimeOut);

      if(!$usenet_handle) {
          echo "Connection failed.\n";
          exit();
      }
      else {
          echo "Connected.\n";
          $tmp = fgets($usenet_handle, 1024);
      }

?>
与服务器对话

现在我们已经连接到了服务器,可以通过前面打开的socket同服务器对话了。比如说我们要从某个新闻组得到最近的10篇文章。RFC977指出,第一步要用GROUP命令选择正确的新闻组:
GROUP ggg
参数ggg是要选择的新闻组的名字(比如说是"net.news"),这是必需的。可用的新闻组的列表可以用LIST命令得到。选择新闻组的命令成功后,返回组中第一篇和最后一篇文章的文章编号,以及组中文章的数目。
   

下面是一个例子:
    chrome:~$ telnet my.news.host 119
    Trying aa.bb.cc.dd...
    Connected to my.news.host.
    Escape character is '^]'.
    200 my.news.host InterNetNews NNRP server INN 2.2.2 13-Dec-1999 ready (posting ok).
    GROUP alt.test
    211 232 222996 223235 alt.test
    quit
    205 .

    接收到命令 GROUP alt.test 后,服务器返回"211 232 222996 223235 alt.test". 211是RFC中定义的返回码,指示命令已成功执行。返回信息还指出,现在有232篇文章,最早的文章的编号是222996,最新的文章的编号是223235。我们看到,222996+232并不等于223235。丢失的7篇文章因为某种原因被从服务器删除了,可能是因为被它的合法作者取消了(这是可能的,而且很容易做到),或者因为是灌水文章而被删。
   

需要注意的事,有些服务器在选择新闻组之前可能要求身份认证,这取决于这是一个公共的或者是私用的服务器。也有可能服务器允许任何人读取文章,但发表文章需要身份验证。

    <?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, "AUTHINFO PASS ".$cfgPasswd."n");
          $tmp = fgets($usenet_handle, 1024);

          //check error

          if($tmp != "281 Okrn") {
              echo "502 Authentication errorn";
              exit();
          }
  }

  //select newsgroup

  fput($usenet_handle, "GROUP ".$cfgNewsGroup."n");
  $tmp = fgets($usenet_handle, 1024);

  if($tmp == "480 Authentication required for commandrn") {
     echo $tmp;
     exit();
  }

  $info = split(" ", $tmp);
  $first= $info[2];
  $last = $info[3];

  printf("First : %sn", $first);
  printf("Last : %lastn", $last);

?>

 

PHP 相关文章推荐
PHP编程网上资源导航
Oct 09 PHP
PHPlet在Windows下的安装
Oct 09 PHP
怎样在UNIX系统下安装php3
Oct 09 PHP
PHP 编程请选择正确的文本编辑软件
Dec 21 PHP
Godaddy空间Zend Optimizer升级方法
May 10 PHP
解析PHP多种序列化与反序列化的方法
Jun 06 PHP
php获取英文姓名首字母的方法
Jul 13 PHP
PHP几个实用自定义函数小结
Jan 25 PHP
PHP的PDO操作简单示例
Mar 30 PHP
PHP大文件切割上传功能实例分析
Jul 01 PHP
4种Windows系统下Laravel框架的开发环境安装及部署方法详解
Apr 06 PHP
详解Laravel服务容器的优势
May 29 PHP
15个小时----从修改程序到自己些程序
Oct 09 #PHP
用PHP编程开发“虚拟域名”系统
Oct 09 #PHP
在Windows中安装Apache2和PHP4的权威指南
Oct 09 #PHP
自定义PHP分页函数
Oct 09 #PHP
用PHP实现WEB动态网页静态
Oct 09 #PHP
用libtemplate实现静态网页生成
Oct 09 #PHP
初探PHP5
Oct 09 #PHP
You might like
php文件上传表单摘自drupal的代码
2011/02/15 PHP
PHP获取url的函数代码
2011/08/02 PHP
关于URL最大长度限制的相关资料查证
2014/12/23 PHP
学习php设计模式 php实现策略模式(strategy)
2015/12/07 PHP
PHP反射机制原理与用法详解
2017/02/15 PHP
splice slice区别
2006/10/09 Javascript
从Ajax到JQuery Ajax学习
2007/02/14 Javascript
用jquery实现学校的校历(asp.net+jquery ui 1.72)
2010/01/01 Javascript
JavaScript Event学习第六章 事件的访问
2010/02/07 Javascript
jquery动态加载图片数据练习代码
2011/08/04 Javascript
jquery实现每个数字上都带进度条的幻灯片
2013/02/20 Javascript
导入extjs、jquery 文件时$使用冲突问题解决方法
2014/01/14 Javascript
js实现仿百度风云榜可重复多次调用的TAB切换选项卡效果
2015/08/31 Javascript
在JavaScript中call()与apply()区别
2016/01/22 Javascript
javascript数字验证的实例代码(推荐)
2016/08/20 Javascript
KnockoutJS 3.X API 第四章之表单submit、enable、disable绑定
2016/10/10 Javascript
bootstrap中添加额外的图标实例代码
2017/02/15 Javascript
JavaScript使用链式方法封装jQuery中CSS()方法示例
2017/04/07 jQuery
深入理解JS异步编程-Promise
2019/06/03 Javascript
微信小程序一周时间表功能实现
2019/10/17 Javascript
解决vue项目运行提示Warnings while compiling.警告的问题
2020/09/18 Javascript
Django实现组合搜索的方法示例
2018/01/23 Python
python判断数字是否是超级素数幂
2018/09/27 Python
python3 http提交json参数并获取返回值的方法
2018/12/19 Python
python实现弹窗祝福效果
2019/04/07 Python
TensorFlow tf.nn.softmax_cross_entropy_with_logits的用法
2020/04/19 Python
open_basedir restriction in effect. 原因与解决方法
2021/03/14 PHP
既然说Ruby中一切都是对象,那么Ruby中类也是对象吗
2013/01/26 面试题
啤酒销售实习自我鉴定
2013/09/24 职场文书
护士求职推荐信范文
2013/11/23 职场文书
护士自荐信范文
2013/12/15 职场文书
幼师大班个人总结
2015/02/13 职场文书
教师培训学习心得体会
2016/01/21 职场文书
关于使用Redisson订阅数问题
2022/01/18 Redis
如何用六步教会你使用python爬虫爬取数据
2022/04/06 Python
如何使用注解方式实现 Redis 分布式锁
2022/07/23 Redis