Use Sockets in PHP: get files from Usenet. Author: ArmelFauveau original address: www. phpbuilder. netcolumnsarmel20042527.php3 translator: Xu Liqiang feifengxlq@gmail.comwww.phpobject.netblogPHP can open remote
Author: Armel Fauveau
Address: http://www.phpbuilder.net/columns/armel20010427.php3
Xu Liqiang feifengxlq@gmail.com
Http: // www.phpobject.net/blog/
PHP can enable sockets on a remote or local server! Here is a simple example of using socket: connect to the Usenet news server, communicate with the server, and download some articles from a precise news group.
Use PHP to open a Socket
Use fsockopen () to open a Socket. This function exists in both PHP3 and PHP4. The function prototype is as follows:
Intfsockopen
(String hostname,
Int port [,
Int errno [,
String errstr [,
Double timeout])
?>
For a network host, it will establish a TCP Socket to connect to the port of the host name. The host name can be a domain name or IP address. For UDP connections, you must specify the Protocol udp: // hostname. For unix hosts, the host name will be used in the socket path. In this example, the port must be set to 0. Optional timeout can be used to set the number of seconds for connection timeout.
For more information about fsockopen (), visit the http://www.php.net/manual/function.fsockopen.php
Network news Transmission Protocol (NNTP)
Accessing a usenet news server requires a special protocol called NNTP, which is the network news transmission protocol standard. For details about this protocol, refer to html "> http://www.w3.org/protocols/rfc977/rfc977.html. This document describes in detail how to use different commands to connect and talk to the NNTP server.
Connect to the server
To connect to the NNTP server, you need to know the host name (or IP address) of the server and the port on which it will listen. In addition, we recommend that you add a timeout time so that the program will not be frozen when the connection fails.
$ Monitoring server = "your. news. host ";
$ Export Port = 119;
$ Required timeout = 10;
// Open asocket
If (! $ Timeout)
// Without timeout
$ Usenet_handle = fsockopen ($ container server, $ container port );
Else
// With timeout
$ Usenet_handle = fsockopen ($ response server, $ response port, & $ errno, & $ errstr, $ response timeout );
If (! $ Usenet_handle ){
Echo "Connexionfailed ";
Exit ();
}
Else {
Echo "Connected ";
$ Tmp = fgets ($ usenet_handle, 1024 );
}
?>
Interaction with servers
Now we have connected to the server and can interact with the server through the socket connection that we opened previously. Let's say "we want to get the latest 10 articles from a news group" to the server ". RFC977 defines how to select the correct news group command, as follows:
GROUPggg
The required ggg parameter is the name of the news group you want to select, such as net. news. You can use the list command to obtain a valid news list. If a response is selected successfully, The News Number of the first and last two news articles in the group and the estimation of the archived news number are returned.
For example
Chrome :~ $ Telnetmy. news. host 119
Trying aa. bb. cc. dd...
Connected tomy. news. host.
Escape character is ^].
200 my. news. hostInterNetNews NNRP server INN 2.2.2 13-Dec-1999 ready (posting OK ).
GROUP alt. test
211 232 222996 223235alt. test
Quit
205.
When the command "GROUP alt. test" is received, the news server returns "211232 222996 223235 alt. test ". Among them, 211 is the rfc id code (simply explain that the command has been successfully executed-you can obtain more detailed information from the RFC view). There are 232 articles in the returned information description, the index number of the oldest news is 222996, while that of the newest news is 223235. Now let's calculate: 222996 + 232 is not equal to 232235. The Lost article is removed from the server, canceled by the author (yes, this is possible and easy to implement), or deleted.
Be careful, before selecting a news group, the server may need to be authenticated. of course, this is determined by whether the server is public or private. Generally, anyone is allowed to obtain news, but the news must be authenticated.
// $ Login user = "xxxxxx ";
// $ CfgPasswd = "yyyyyy ";
$ Optional newsgroup = "alt. php ";
// Identification required on private server
If ($ login user ){
Fputs ($ usenet_handle, "authinfo user". $ your USER ."");
$ Tmp = fgets ($ usenet_handle, 1024 );
Fputs ($ usenet_handle, "AUTHINFOPASS". $ cfgPasswd ."");
$ Tmp = fgets ($ usenet_handle, 1024 );
// Check error
If ($ tmp! = "281Ok "){
Echo "502 Authentication error ";
Exit ();
}
}
// Select newsgroup
Fputs ($ usenet_handle, "GROUP". $ Using newsgroup ."");
$ Tmp = fgets ($ usenet_handle, 1024 );
If ($ tmp = "480 Authentication required for command "){
Echo "$ tmp ";
Exit ();
}
$ Info = split ("", $ tmp );
$ First = $ info [2];
$ Last = $ info [3];
Print "First: $ first ";
Print "Last: $ last ";
?>
Get some articles
Now we have the index number of the latest article A, so we can easily get the latest 10 articles. RFC977 indicates that the ARTICLE command can be used with the index number or message ID of the ARTICLE. To be careful, the index number and message ID of the article are different here, because each news server has different definitions, therefore, the index numbers of the same article on different news servers are different, but the message ID is unique (included in the header of the article)
$ CfgLimit = 10;
// Upload last articles
$ Boucle = $ last-$ cfgLimit;
While ($ boucle <= $ last ){
Set_time_limit (0 );
Fputs ($ usenet_handle, "ARTICLE $ boucle ");
$ Article = "";
$ Tmp = fgets ($ usenet_handle, 4096 );
If (substr ($ tmp, 0, 3 )! = & Quot; 220 & quot "){
Echo "+ ---------------------- + ";
Echo "Error onarticle $ boucle ";
Echo "+ ---------------------- + ";
}
Else {
While ($ tmp! = "."){
$ Tmp = fgets ($ usenet_handle, 4096 );
$ Article = $ article. $ tmp;
}
Echo "+ ---------------------- + ";
Echo "Article $ boucle ";
Echo "+ ---------------------- + ";
Echo "$ article ";
}
$ Boucle ++;
}
?>
We only obtained 10 latest news from this server group. You can also use the HEAD command to obtain the header information of the article, or use the BODY command to obtain the BODY of the news.
Close connection
With the fclose () function, you can end the session with the NNTP server. of course, you can create a new file, as shown below:
// Close connexion
Fclose ($ usenet_handle );
?>