在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 相关文章推荐
数字转英文
Dec 06 PHP
将文件夹压缩成zip文件的php代码
Dec 14 PHP
php站内搜索并高亮显示关键字的实现代码
Dec 29 PHP
php 如何获取数组第一个值
Aug 06 PHP
初识Laravel
Oct 30 PHP
ThinkPHP自动完成中使用函数与回调方法实例
Nov 29 PHP
PHP中字符串长度的截取用法示例
Jan 12 PHP
PHP实现多级分类生成树的方法示例
Feb 07 PHP
PHP __call()方法实现委托示例
May 20 PHP
Thinkphp自定义生成缩略图尺寸的方法
Aug 05 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
Nov 24 PHP
php利用ZipArchive类操作文件的实例
Jan 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
Body是什么,该怎么喝出咖啡里的口感
2021/03/03 咖啡文化
手把手教你使用DedeCms的采集的图文教程
2007/03/11 PHP
php中mysql连接和基本操作代码(快速测试使用,简单方便)
2014/04/25 PHP
php通过array_push()函数添加多个变量到数组末尾的方法
2015/03/18 PHP
php中session_id()函数详细介绍,会话id生成过程及session id长度
2015/09/23 PHP
ThinkPHP中获取指定日期后工作日的具体日期方法
2018/10/14 PHP
multiSteps 基于Jquery的多步骤滑动切换插件
2011/07/22 Javascript
页面只能打开一次Cooike如何实现
2012/12/04 Javascript
document.forms用法示例介绍
2014/06/26 Javascript
jquery实现无限分级横向导航菜单的方法
2015/03/12 Javascript
js输出数据精确到小数点后n位代码
2016/07/02 Javascript
微信小程序 实战程序简易新闻的制作
2017/01/09 Javascript
vue中使用localstorage来存储页面信息
2017/11/04 Javascript
微信小程序progress组件使用详解
2018/01/31 Javascript
vue 录制视频并压缩视频文件的方法
2018/07/27 Javascript
js前端如何写一个精确的倒计时代码
2019/10/25 Javascript
es6函数之尾调用优化实例分析
2020/04/25 Javascript
Vue组件生命周期运行原理解析
2020/11/25 Vue.js
[35:34]Liquid vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python利用elaphe制作二维条形码实现代码
2012/05/25 Python
探寻python多线程ctrl+c退出问题解决方案
2014/10/23 Python
Python统计文件中去重后uuid个数的方法
2015/07/30 Python
pycharm下打开、执行并调试scrapy爬虫程序的方法
2017/11/29 Python
Python并发:多线程与多进程的详解
2019/01/24 Python
python画双y轴图像的示例代码
2019/07/07 Python
中国制造网:Made-in-China.com
2019/10/25 全球购物
先进个人事迹材料
2014/01/25 职场文书
内衣营销方案
2014/03/15 职场文书
儿童生日会策划方案
2014/05/15 职场文书
关爱残疾人演讲稿
2014/05/24 职场文书
专题民主生活会对照检查材料思想汇报
2014/09/29 职场文书
爱心募捐感谢信
2015/01/22 职场文书
优秀党员个人总结
2015/02/14 职场文书
学校元旦晚会开场白
2015/05/29 职场文书
2016年小学植树节活动总结
2016/03/16 职场文书
2019奶茶店创业计划书范本,值得你借鉴
2019/08/14 职场文书