Autor: Armel Fauveau
Endereço original: http://www.phpbuilder.net/columns/armel20010427.php3
Tradutor: Xu [email protected]
http://www.phpobject.net/blog/
PHP pode abrir soquetes de servidores remotos ou locais! Aqui está um exemplo simples usando soquetes: conecte-se a um servidor de notícias Usenet, comunique-se com o servidor e baixe alguns artigos de um grupo de notícias específico.
Abra o soquete usando PHP
Use fsockopen() para abrir um Socket. Esta função existe tanto no PHP3 quanto no PHP4. O protótipo da função é o seguinte:
<?php
intfsockopen
(string nome do host,
porta interna[,
int errno[,
string errstr[,
tempo limite duplo]]])
?>
Para hosts de rede, ele estabelecerá uma conexão TCP Socket com a porta do nome do host. O nome do host pode ser um nome de domínio ou um endereço IP. Para conexões UDP, você precisa especificar o protocolo: udp://hostname. Para hosts unix, o nome do host será usado no caminho para o soquete e a porta deve ser definida como 0 neste exemplo. O tempo limite opcional pode ser usado para definir o número de segundos para o tempo limite da conexão.
Mais informações sobre fsockopen() podem ser encontradas em http://www.php.net/manual/function.fsockopen.php
Protocolo de transferência de notícias de rede (NNTP)
O acesso a um servidor de notícias da Usenet requer o uso de um protocolo especial chamado NNTP, o padrão Network News Transfer Protocol. Os detalhes deste protocolo estão no RFC977, que você pode visualizar em http://www.w3.org/Protocols/rfc977/rfc977.html . Este documento descreve detalhadamente como usar diferentes comandos para conectar e comunicar-se com um servidor NNTP.
Servidor de Conexão Conectar-se a um servidor NNTP requer saber o nome do host do servidor (ou endereço IP) e a porta na qual ele irá escutar. Também é recomendável adicionar um tempo limite para que o programa não “trave” quando a conexão falhar.
<?php
$cfgServer="seu.news.host";
$cfgPort =119;
$cfgTimeOut =10;
//abre um soquete
if(!$cfgTimeOut)
// sem tempo limite
$usenet_handle=fsockopen($cfgServer,$cfgPort);
outro
//com tempo limite
$usenet_handle=fsockopen($cfgServer,$cfgPort, &$errno, &$errstr,$cfgTimeOut);
if(!$usenet_handle) {
echo"Falha na conexãon";
saída();
}
outro {
echo"Conectadon";
$tmp=fgets($usenet_handle,1024);
}
?>
Interagindo com o Servidor Agora estamos conectados ao servidor e podemos interagir com o servidor através da conexão de soquete aberta anteriormente. Digamos ao servidor "Queremos obter os 10 artigos mais recentes de um determinado grupo de notícias". RFC977 define o comando sobre como selecionar o agrupamento de notícias correto, como segue:
GRUPOggg
O parâmetro obrigatório ggg é o nome do grupo de notícias que você deseja selecionar, como net.news. Usando o comando list você pode obter uma lista de notícias válida. Uma resposta de seleção bem-sucedida retornará os números das notícias do primeiro e dos dois últimos artigos de notícias do grupo e uma estimativa dos números das notícias arquivadas.
por exemplo
cromo:~$ telnetmy.news.host 119
Tentando aa.bb.cc.dd...
Conectado amy.news.host.
O caractere de escape é '^]'.
200 my.news.hostInterNetNews Servidor NNRP INN 2.2.2 pronto em 13 de dezembro de 1999 (postagem ok).
GRUPO alt.teste
211 232 222996 223235alt.teste
desistir
205.
Após receber o comando "GROUP alt.test", o servidor de notícias retornou "211232 222996 223235 alt.test". 211 é o código de identificação RFC (uma explicação simples de que o comando foi executado com sucesso - verifique o RFC para obter informações mais detalhadas). A informação retornada indica que existem 232 artigos, entre os quais o número de índice da notícia mais antiga é 222996, e o número do índice da notícia mais antiga é 222996). mais recente O número do índice de notícias é 223235. Agora vamos fazer as contas: 222996+232 não é igual a 232235. O artigo perdido foi removido do servidor, cancelado pelo autor (sim, é possível e fácil de fazer) ou excluído.
Como precaução, o servidor poderá exigir autenticação antes de selecionar um grupo de notícias, dependendo se o servidor for público ou privado. Geralmente, qualquer pessoa pode obter notícias, mas a publicação de notícias exige certificação.
<?php
//$cfgUser = "xxxxxx";
//$cfgPasswd = "aaaa";
$cfgNewsGroup="alt.php";
//identificação necessária no servidor privado
if($cfgUsuário) {
fputs($usenet_handle,"AUTHINFO USER".$cfgUser."n");
$tmp=fgets($usenet_handle,1024);
fputs($usenet_handle,"AUTHINFOPASS".$cfgPasswd."n");
$tmp=fgets($usenet_handle,1024);
//verifica o erro
if($tmp!="281Okrn") {
echo "502Erro de autenticaçãon";
saída();
}
}
//seleciona o grupo de notícias
fputs($usenet_handle,"GRUPO ".$cfgNewsGroup."n");
$tmp=fgets($usenet_handle,1024);
if($tmp=="480 Autenticação necessária para comandorn") {
echo "$tmpn";
saída();
}
$info=split(" ",$tmp);
$primeiro=$info[2];
$último=$info[3];
print"Primeiro: $primeiron";
print"Último: $últimon";
?>
Obtenha alguns artigos Agora que temos o número de índice A do artigo mais recente, podemos facilmente obter os dez artigos mais recentes. RFC977 afirma que o comando ARTICLE pode ser usado com o número de índice do artigo ou ID da mensagem. Por uma questão de cautela, aqui o número de índice do artigo e o ID da mensagem são diferentes. Como cada servidor de notícias tem definições diferentes, o número de índice do mesmo artigo em diferentes servidores de notícias será diferente, mas o ID da mensagem deve ser. exclusivo (incluído no cabeçalho do artigo)
<?php
$cfgLimite=10;
// carrega os últimos artigos
$boucle=$último-$cfgLimit;
enquanto ($boucle<=$último) {
set_time_limit(0);
fputs($usenet_handle,"ARTICLE$bouclen");
$artigo="";
$tmp=fgets($usenet_handle,4096);
if(substr($tmp,0,3) !="220") {
eco"+----------------------+n";
echo"Erro no artigo $bouclen";
eco"+----------------------+n";
}
outro {
enquanto($tmp!=".rn") {
$tmp=fgets($usenet_handle,4096);
$artigo=$artigo.$tmp;
}
eco"+----------------------+n";
echo"Artigo$bouclen";
eco"+----------------------+n";
echo"$artigon";
}
$bouclé++;
}
?>
Recebemos apenas as dez últimas notícias deste grupo neste servidor. Você também pode usar o comando HEAD para obter as informações do cabeçalho do artigo ou o comando BODY para obter o corpo da notícia.
Feche a conexão e use a função fclose() para encerrar a sessão com o servidor NNTP. Claro, você pode criar um novo arquivo da seguinte maneira:
<?php
//fecha a conexão
fclose($usenet_handle);
?>
Para mais informações sobre fclose(), consulte: http://www.php.net/manual/function.fclose.php
Conclusão Neste artigo, mostramos apenas como abrir, usar e fechar uma conexão de soquete sob determinadas circunstâncias: conectar-se a um servidor NNTP e recuperar alguns artigos do grupo de notícias. Publicar um artigo em um servidor NNTP usando o comando POST não é muito mais complicado.
Portanto, o próximo passo é escrever um cliente de notícias (e retirar um pouco do Netscape) que possa facilmente salvar artigos e indexá-los usando algum mecanismo de busca (como htgid, http://www.htdig.org/), e deve haver um aplicativo WEB que pode realizar pesquisas por palavras-chave em grupos de notícias. Aqui está um exemplo, você pode visitar http://www.phpindex.com/ng/ para baixá-lo.