Sockets using in PHP
PHP can open sockets both on the local and remote computer. In that article we will view the example of using sockets for Usenet server connecting and downloading some articles.
Open the socket
We use fsockopen() function for opening the socket. That function is available both in the PHP 3 and PHP 4. That function call looks as follows:
int fsockopen (string hostname, int port [, int errno [, string errstr [, double timeout]]])
UDP connection requires the udp //hostname protocol.
NNTP-protocol (Network News Transfer Protocol)
For accessing the news usenet server we’ll use the NNTP protocol. That protocol is described in the RFC977 (Request For Comment number 977). That document describes the connecting and dialog process.
Connecting
For connecting to the NNTP server we have to know its name (or IP address) and port. Also we have to indicate timer for preventing the application “freeze” in the case of the connecting error.
<?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 "Connexion failed\n";
exit();
}
else {
echo "Connected\n";
$tmp = fgets($usenet_handle, 1024);
}
?>
Dialog with server.
So, we have already connected to the server, that’s why we can dialog with it using opened socket. As an example we’ll try to get last ten messages from any group. In RFC977 there is written that the first step is to select the group with the help of the GROUP command:
GROUP ggg
ggg is a required parameter, which means the group’s name we are going to select (for example "net.news"). The list of the received groups can be got using the LIST command. Successful group selection will confirmed with the server’s response that will include the amount of the new and old articles.
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
After receiving the "GROUP alt.test" command news server responds "211 232 222996 223235 alt.test". 211 is a code defined by the RFC specification (in other words it means that command has the positive result). 232 is the amount of the new articles for the current moment. 222996 is the amount of the old articles. 223235 is a total amount.
According to the server’s type (public or private) there can be asked the identification. However, identification can be required only if you write messages.
<?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 Ok\r\n") {
echo "502 Authentication 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";
?>
Articles downloading
Now we have the number of the last article so there are no any problems for downloading last ten articles. RFC977 specification allows using ARTICLE command both with article number and Message ID.
Be careful! Message ID and article number have different meanings. If the article is published on different servers it will have different number but the same Message 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 on article $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++;
}
?>
Using the HEAD command you can get only message header, using BODY command you can get only text.
Disconnection
For closing the session with NTP server just close the socket using fclose() function
<?php
// close connexion
fclose($usenet_handle);
?>
Summary
So, you could see how to open, use and close the socket for connecting to the NTP server and getting some articles from the news groups. For publishing the message you have to use the POST command.



