我们已经提到了两个 NNTP 命令,它们是新闻文章在服务器之间推送或拉取的关键。现在我们将在实际的 NNTP 会话上下文中查看这些命令,向您展示该协议是多么简单。为了便于说明,我们将使用一个简单的 telnet 客户端连接到 Virtual Brewery 的基于 INN 的新闻服务器,名为 news.vbrew.com。该服务器运行的是最小配置,以使示例简短。我们将在 第 23 章 中介绍如何完成此服务器的配置。在我们的测试中,我们将非常小心地仅在 junk 新闻组中生成文章,以避免打扰任何人。
连接到新闻服务器就像打开到其 NNTP 端口的 TCP 连接一样简单。连接后,您将看到一个欢迎标语。您可能尝试的第一个命令之一是 help。您收到的响应通常取决于服务器是否认为您是远程 NNTP 服务器还是新闻阅读器,因为需要不同的命令集。您可以使用 mode 命令更改您的操作模式;我们稍后会介绍这一点
$ telnet news.vbrew.com nntp Trying 172.16.1.1... Connected to localhost. Escape character is '^]'. 200 news.vbrew.com InterNetNews server INN 1.7.2 08-Dec-1997 ready help 100 Legal commands authinfo help ihave check takethis list mode xmode quit head stat xbatch xpath xreplic For more information, contact "usenet" at this machine. . |
对 NNTP 命令的响应总是以单独一行的句点 (.) 结尾。您在输出列表中看到的数字是 响应代码,服务器使用它们来指示命令的成功或失败。响应代码在 RFC-977 中描述;我们将在继续的过程中讨论最重要的代码。
当我们谈到将新闻文章推送到新闻服务器时,我们提到了 IHAVE 命令。现在让我们看一下 IHAVE 命令的实际工作原理
ihave <123456@gw.vk2ktj.ampr.org> 335 From: terry@gw.vk2ktj.ampr.org Subject: test message sent with ihave Newsgroups: junk Distribution: world Path: gw.vk2ktj.ampr.org Date: 26 April 1999 Message-ID: <123456@gw.vk2ktj.ampr.org> Body: This is a test message sent using the NNTP IHAVE command. . 235 |
所有 NNTP 命令都不区分大小写,因此您可以以大写或小写形式输入它们。IHAVE 命令接受一个强制性参数,即正在推送的文章的消息 ID。每篇新闻文章在创建时都会被分配一个唯一的消息 ID。IHAVE 命令提供了一种让 NNTP 服务器在想要将文章推送到另一台服务器时说明其拥有的文章的方式。发送服务器将为其希望推送的每篇文章发出 IHAVE 命令。如果接收 NNTP 服务器生成的命令响应代码在“3xx”范围内,则发送 NNTP 服务器将传输完整的文章,包括其完整的标头,并以单独一行的句点结尾。如果响应代码在“4xx”范围内,则接收服务器已选择不接受此文章,可能是因为它已经拥有该文章,或者由于某些问题,例如磁盘空间不足。
当文章传输完成后,接收服务器会发出另一个响应代码,指示文章传输是否成功。
新闻阅读器在与新闻服务器通信时使用自己的一组命令。要激活这些命令,新闻服务器必须在 阅读器 模式下运行。大多数新闻服务器默认为阅读器模式,除非连接主机的 IP 地址被列为新闻转发对等方。在任何情况下,NNTP 都提供了一个命令来显式切换到阅读器模式
mode reader 200 news.vbrew.com InterNetNews NNRP server INN 1.7.2 08-Dec-1997 ready/ (posting ok). help 100 Legal commands authinfo user Name|pass Password|generic <prog> <args> article [MessageID|Number] body [MessageID|Number] date group newsgroup head [MessageID|Number] help ihave last list [active|active.times|newsgroups|distributions|distrib.pats|/ overview.fmt|subscriptions] listgroup newsgroup mode reader newgroups yymmdd hhmmss ["GMT"] [<distributions>] newnews newsgroups yymmddhhmmss ["GMT"] [<distributions>] next post slave stat [MessageID|Number] xgtitle [group_pattern] xhdr header [range|MessageID] xover [range] xpat header range|MessageID pat [morepat...] xpath MessageID Report problems to <usenet@vlager.vbrew.com> . |
NNTP 阅读器模式有很多命令。其中许多命令旨在使新闻阅读器的生活更轻松。我们之前提到过,有些命令指示服务器分别发送文章的头部和正文。还有一些命令列出可用的组和文章,以及其他允许发布的命令,这是一种将新闻文章发送到服务器的替代方法。
list 命令列出了许多不同类型的信息;特别是服务器支持的组
list newsgroups 215 Descriptions in form "group description". control News server internal group junk News server internal group local.general General local stuff local.test Local test group . |
list active显示每个受支持的组,并提供有关它们的信息。输出中每行的两个数字是高水位标记和低水位标记——即每个组中编号最高的文章和编号最低的文章。新闻阅读器能够从中了解该组中文章的数量。我们稍后会详细讨论这些数字。输出中的最后一个字段显示控制是否允许向该组发布、该组是否经过审核以及发布的文章是实际存储还是仅传递的标志。这些标志在 第 23 章 中详细描述。一个例子看起来像这样
list active 215 Newsgroups in form "group high low flags". control 0000000000 0000000001 y junk 0000000003 0000000001 y alt.test 0000000000 0000000001 y . |
我们提到过推送文章和发布文章之间存在差异。当您推送文章时,存在一个隐含的假设,即该文章已经存在,它有一个消息标识符,该标识符已由最初发布该文章的服务器唯一分配给它,并且它具有完整的标头集。当发布文章时,您是第一次创建文章,并且您提供的唯一标头是对您有意义的标头,例如主题和您要发布文章的新闻组。您发布文章的新闻服务器将为您添加所有其他标头,并创建一个消息 ID,以便在将文章推送到其他服务器时使用。
所有这些都意味着发布文章甚至比推送文章更容易。一个发布示例看起来像这样
post 340 Ok From: terry@richard.geek.org.au Subject: test message number 1 Newsgroups: junk Body: This is a test message, please feel free to ignore it. . 240 Article posted |
我们生成了另外两条类似的消息,以便为我们下面的示例提供一些真实感。
当新闻阅读器首次连接到新服务器并且用户选择要浏览的新闻组时,新闻阅读器将希望检索新文章列表,即用户上次登录以来发布或接收的文章。newnews命令用于此目的。必须提供三个强制性参数:要查询的组的名称,开始日期和开始时间,从中列出。日期和时间均指定为六位数字,最重要的信息在前;yymmdd和hhmmss, 分别
newnews junk 990101 000000 230 New news follows <7g2o5r$aa$6@news.vbrew.com> <7g5bhm$8f$2@news.vbrew.com> <7g5bk5$8f$3@news.vbrew.com> . |
当用户选择要浏览的新闻组时,新闻阅读器可以告诉新闻服务器已选择该组。这简化了新闻阅读器和新闻服务器之间的交互;它消除了每次命令都需要不断发送新闻组名称的需要。group命令仅将所选组的名称作为参数。许多后续命令都使用所选组作为默认值,除非明确指定了另一个新闻组
group junk 211 3 1 3 junk |
该group命令返回一条消息,指示活动消息的数量、低水位标记、高水位标记以及组的名称,分别。请注意,虽然在我们的示例中活动消息的数量和高水位标记相同,但通常情况并非如此;在活动新闻服务器中,某些文章可能已过期或被删除,从而降低了活动消息的数量,但保持高水位标记不变。
要寻址新闻组文章,新闻阅读器必须知道哪些文章编号代表活动文章。listgroup命令提供当前组中或显式组(如果提供了组名)中活动文章编号的列表
listgroup junk 211 Article list follows 1 2 3 . |
用户必须拥有有关文章的一些信息,然后才能知道她是否希望阅读它。我们之前提到过,某些命令允许分别传输文章标头和正文。head命令用于请求服务器仅将指定文章的标头传输到新闻阅读器。如果用户不想阅读此文章,我们就不会浪费时间和网络带宽来不必要地传输可能很大的文章正文。
文章可以使用其编号(来自listgroup命令)或其消息标识符引用
head 2 221 2 <7g5bhm$8f$2@news.vbrew.com> head Path: news.vbrew.com!not-for-mail From: terry@richard.geek.org.au Newsgroups: junk Subject: test message number 2 Date: 27 Apr 1999 21:51:50 GMT Organization: The Virtual brewery Lines: 2 Message-ID: <7g5bhm$8f$2@news.vbrew.com> NNTP-Posting-Host: localhost X-Server-Date: 27 Apr 1999 21:51:50 GMT Body: Xref: news.vbrew.com junk:2 . |
另一方面,如果用户决定她确实想阅读该文章,则她的新闻阅读器需要一种请求传输消息正文的方法。body命令用于此目的。它的操作方式与head命令非常相似,只是只返回消息正文
body 2 222 2 <7g5bhm$8f$2@news.vbrew.com> body This is another test message, please feel free to ignore it too. . |
虽然通常最有效的方法是分别传输所选文章的标头和正文,但在某些情况下,我们最好传输完整的文章。这方面的一个很好的例子是在我们想要传输组中所有文章而没有任何预选的应用程序中,例如当我们使用像 leafnode 这样的 NNTP 缓存程序时。[1]
自然地,NNTP 提供了一种执行此操作的方法,并且毫不奇怪,它的操作方式几乎与head命令相同。article命令也接受文章编号或消息 ID 作为参数,但返回整个文章,包括其标头
article 1 220 1 <7g2o5r$aa$6@news.vbrew.com> article Path: news.vbrew.com!not-for-mail From: terry@richard.geek.org.au Newsgroups: junk Subject: test message number 1 Date: 26 Apr 1999 22:08:59 GMT Organization: The Virtual brewery Lines: 2 Message-ID: <7g2o5r$aa$6@news.vbrew.com> NNTP-Posting-Host: localhost X-Server-Date: 26 Apr 1999 22:08:59 GMT Body: Xref: news.vbrew.com junk:1 This is a test message, please feel free to ignore it. . |
如果您尝试检索未知文章,服务器将返回一条消息,其中包含适当编码的响应代码,可能还有一条可读的文本消息
article 4 423 Bad article number |
我们在本节中描述了最重要的 NNTP 命令是如何使用的。如果您有兴趣开发实现 NNTP 协议的软件,则应参考相关的 RFC 文档;它们提供了我们无法在此处包含的大量细节。
现在让我们通过 nntpd 服务器来了解 NNTP 的实际应用。
[1] | leafnode 可通过匿名 FTP 从 wpxx02.toxi.uni-wuerzburg.de 获取,位于/pub/目录中。 |