在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中使用Oracle数据库(1)
Oct 09 PHP
PHP VS ASP
Oct 09 PHP
一段php加密解密的代码
Jul 16 PHP
php 随机数的产生、页面跳转、件读写、文件重命名、switch语句
Aug 07 PHP
献给php初学者(入门学习经验谈)
Oct 12 PHP
关于php curl获取301或302转向的网址问题的解决方法
Jun 02 PHP
在PHP上显示JFreechart画的统计图方法
Nov 03 PHP
PHP生成数组再传给js的方法
Aug 07 PHP
实例讲解php数据访问
May 09 PHP
Smarty变量用法详解
May 11 PHP
PHP自定义函数实现数组比较功能示例
Oct 19 PHP
PHP pthreads v3下worker和pool的使用方法示例
Feb 21 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
COM in PHP (winows only)
2006/10/09 PHP
朋友网关于QQ相关的PHP代码(研究QQ的绝佳资料)
2015/01/26 PHP
ThinkPHP项目分组配置方法分析
2016/03/23 PHP
PHP使用imagick扩展实现合并图像的方法
2017/04/25 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
PHP+Ajax实现上传文件进度条动态显示进度功能
2018/06/04 PHP
Laravel自定义 封装便捷返回Json数据格式的引用方法
2019/09/29 PHP
Javascript优化技巧(文件瘦身篇)
2008/01/28 Javascript
JavaScript 未结束的字符串常量常见解决方法
2010/01/24 Javascript
JS分页控件 可用于无刷新分页
2013/07/23 Javascript
document.forms用法示例介绍
2014/06/26 Javascript
使用AngularJS实现可伸缩的页面切换的方法
2015/06/19 Javascript
C++中的string类的用法小结
2015/08/07 Javascript
JS控制页面跳转时未请求要跳转的地址怎么回事
2016/10/14 Javascript
AngularJS实现与Java Web服务器交互操作示例【附demo源码下载】
2016/11/02 Javascript
bootstrap表单按回车会自动刷新页面的解决办法
2017/03/08 Javascript
javascript自定义事件功能与用法实例分析
2017/11/08 Javascript
jquery ajax加载数据前台渲染方式 不用for遍历的方法
2018/08/09 jQuery
vue中,在本地缓存中读写数据的方法
2018/09/21 Javascript
简单实现节流函数和防抖函数过程解析
2019/10/08 Javascript
Angular 多级路由实现登录页面跳转(小白教程)
2019/11/19 Javascript
[00:30]塑造者的传承礼包-戴泽“暗影之焰”套装展示视频
2014/04/04 DOTA
python直接访问私有属性的简单方法
2016/07/25 Python
解决python写入mysql中datetime类型遇到的问题
2018/06/21 Python
windows下搭建python scrapy爬虫框架步骤
2018/12/23 Python
python中下标和切片的使用方法解析
2019/08/27 Python
Linux安装Python3如何和系统自带的Python2并存
2020/07/23 Python
Python类的继承super相关原理解析
2020/10/22 Python
python文件路径操作方法总结
2020/12/21 Python
贝玲妃美国官方网站:Benefit美国
2016/08/28 全球购物
小区门卫工作职责
2013/12/14 职场文书
幼儿园家长会邀请函
2014/01/15 职场文书
销售经理岗位职责
2014/03/16 职场文书
建筑公司员工自我鉴定
2014/04/08 职场文书
领导走群众路线整改措施思想汇报
2014/10/12 职场文书
MySQL脏读,幻读和不可重复读
2022/05/11 MySQL