• Artigos
  • Projetos
  • Download
  • Lista
  • Docs
  • Comunidade
  • ?

Conexão Via Socket

20/12/2007  Josemary Lopes  Ler e Comentar

Aplicação é dividida em duas partes, uma será o server que ficará "ouvindo" uma porta pré definida e a outra parte é o client que fará o acesso via sockets nesse servidor para trocar informações. O client enviará um dado e o server recebendo consultará o bd, SQLITE, e retornará para o client o resultado da pesquisa..


Nesse caso o server e o client estao na mesma máquina q tem o PHP GTK instalado.

server.php
<code>
<?php
    define
('MAXLINE', 1024); //TAMANHO DO SOCKET RECEBIDO
    
define('LISTENQ', 1);  
    
define('PORT', 81);      //PORTA PADRÃO PARA CONEXÃO
    
define('FD_SETSIZE', 2); //Nº MÁXIMO DE CLIENTES PERMITIDO POR CONEXÃO
        
    //PARA MATAR O SERVIDOR
    
function killDaemon()
    {
        global 
$listenfd, $client;
        
$msg = "Fechando servidor!!
"
;
        for (
$i = 0; $i < FD_SETSIZE; $i++)
        {
            if (
$client[$i] != null)
            {
                
socket_write($client[$i], $msg, strlen($msg));
                
socket_close($client[$i]);
            }
        }
        print 
"DESCONECTAR!!
"
;
        
socket_close($listenfd);
        exit;
    }
        
    
//QUANDO O CLIENTE DESCONECTAR
    
function closeClient($i)
    {
        global 
$client, $remote_host, $remote_port;
        print 
"closing client[$i] ({$remote_host[$i]}:{$remote_port[$i]})
"
;
        
socket_close($client[$i]);
        
$client[$i] = null;
        unset(
$remote_host[$i]);
                
        
//VERIFICA SE HÁ CLIENTE CONECTADO, FAZ O DESCONECT
        
$someoneconnected = false;
        
        for (
$i = 0; $i <= FD_SETSIZE; $i++)
        {
            if(
$client[$i] != null)
            {
                
$someoneconnected = true;
                break;
            }
        }
        
        if(
$someoneconnected == false)
        {
            
//killDaemon();
        
}
    }
    
    
//CONECTA COM SQLITE
    
function conecta()
    {
        global 
$db; 

         
//caso a base de dados não exista, ele tenta criar
        
if ($db = sqlite_open("C:/Documents and Settings/josy/Desktop/sqlite/teste.db", 0666, $error))        
            return 
$db;
        else
            die(
$error);
    }
    
    function 
consulta($n,$db)
    {
        global 
$resultado;
        
        
$sql       = sqlite_query($db, "SELECT id, nome, numero FROM consulta WHERE numero=$n");
        
$i         = sqlite_fetch_array($sql);
        
$resultado = "ID: ".$i['id']." Nome: ".$i['nome']." Número: ".$i['numero'];    
    }
        
    
$listenfd = socket_create(AF_INET, SOCK_STREAM, 0);
        
    if (
$listenfd)
        print 
"Escutando a porta " . PORT . "
"
;
    else
        die(
"Socket morreu!!
"
);
    
    
//CONFIGURAÇÃO IP DO SERVER
    
socket_setopt($listenfd, SOL_SOCKET, SO_REUSEADDR, 0); 
    if (!
socket_bind($listenfd, "0.0.0.0", PORT))
    {
        
socket_close($listenfd);
        die(
"Não foi possível conectar!!
"
);
    }
    
socket_listen($listenfd, LISTENQ);
        
    for (
$i = 0; $i < LISTENQ; $i++)
        
$client[$i] = null;
        
    while(
1)
    {
        
$rfds[0] = $listenfd;
        {
            for (
$i = 0; $i <= FD_SETSIZE; $i++)
                if (
$client[$i] != null)
                    
$rfds[$i + 1] = $client[$i];
        }
        
        
//BLOQUEIA INDEFINITAMENTE ATÉ RECEBER UMA CONEXÃO
        
$nready = socket_select($rfds, $null, $null, null);
                
        
//SE TEMOS UMA CONEXÃO
        
if (in_array($listenfd, $rfds))
        {
            print 
"Criando novo cliente!!
"
;//LISTENFD OUVIU ALGO
            
            //CONECTA COM SQLITE
            
conecta();
            
            
//PEGA O NOVO LOCAL
            
for ($i = 0; $i <= FD_SETSIZE; $i++)
            {
                if (
$client[$i] == null)
                {
                    
$client[$i] = socket_accept($listenfd);
                    
socket_setopt($client[$i], SOL_SOCKET, SO_REUSEADDR, 0);
                    
socket_getpeername($client[$i], $remote_host[$i], $remote_port[$i]);
                    print 
"Aceitar {$remote_host[$i]}:{$remote_port[$i]} as client[$i]
"
;
                                
                    if (
$i < FD_SETSIZE)
                    {
                        break;
                    }
                }
                
                if (
$i >= FD_SETSIZE)
                {
                    
//NO CASO DE MUITOS CLIENTES
                    
closeClient($i);
                    break;
                }
            }
            if (--
$nready <= 0)
            continue;
        }
        
        
        
//VERIFICA OS CLIENTES PARA RECEPÇÃO DE DADOS
        
for ($i = 0; $i <= FD_SETSIZE; $i++)
        {
            if (
$client[$i] == null)
                continue;
            
            if (
in_array($client[$i], $rfds))
            {
                
$n = trim(socket_read($client[$i], MAXLINE));
                
                if (!
$n)
                    
closeClient($i);
                else
                {
                    
//QDO O CLIENTE ENVIA OS DADOS ABAIXO
                    
if ($n == "/killme")
                        
killDaemon();
                    else if (
$n == "/quit")
                        
closeClient($i);
                    else
                    {
                        
//IMPRIME ALGO NO SERVIDOR
                        
print "From {$remote_host[$i]}:{$remote_port[$i]}>client[$i]: $n
"
;
                        
                        for (
$j = 0; $j <= FD_SETSIZE; $j++)
                        {
                            if (
$client[$j] != null)
                            {
                                
//CONSULTA VALOR DIGITADO NO CLIENT PARA A FUNÇAÕ
                                
consulta($n,$db);
                                
                                
//ESCREVE A RESPOSTA PARA O CLIENT
                                
socket_write($client[$j], $resultado);
                            }    
                        }
                    }
                }
                
                if (--
$nready <= 0)
                    break;
            }
        }
    }

?>


</code>


client.php
<code>
<?
     
class MyClass
     
{
          private 
$socket;
          
          function 
MyClass()
         {
               
$server = $this->server = '127.0.0.1';
               
$port   = $this->port   = '81';
               
              
$window = $this->window = new GtkWindow();
              
$window->set_title('..: CLIENT SOCKET :..');
              
$window->set_default_size(436,337);
              
$fixed = $this->fixed = new GtkFixed();
              
              
//CENTRALIZA JANELA
              
$window->set_position(GTK::WIN_POS_CENTER);
              
              
$this->conecta($this->server, $this->port); //CHAMA CONEXÃO VIA SOCKETS
              
$pixbuf = GdkPixbuf::new_from_file('C:php-gtk2
ovoimageslogo_pequeno.jpg'
);
              
$imagem = new GtkImage;
              
$imagem->set_from_pixbuf($pixbuf);
              
$nome_cliente = $this->nome_cliente = new GtkLabel('Cliente:');
              
$input_nome = $this->input_nome = new GtkEntry();
              
$buttom = $this->buttom = new GtkToggleButton('Pesquisar');
              
$buttom->connect("clicked",array($this, "pesquisa"));
              
$adj5 = new GtkAdjustment(0, 0, 100, 1, 0, 0);
              
$progress = $this->progress = new GtkProgressBar( $adj5 );
              
$caixa = $this->caixa = new GTKTextView;
              
$textbuffer = $this->textbuffer = new GtkTextBuffer;
              
$this->caixa->set_buffer($this->textbuffer);
              
$this->textbuffer->set_text('');
                                                  
              
$input_nome->set_size_request(185,25);
              
$buttom->set_size_request(75,25);
              
$progress->set_size_request(170,25);
              
$caixa ->set_size_request(400,90);                  
                          
              
$fixed->put($imagem,14,11);
              
$fixed->put($nome_cliente,168,97);
              
$fixed->put($input_nome,221,91);
              
$fixed->put($buttom,177,137);
              
$fixed->put($progress,125,180);
              
$fixed->put($caixa,18,230);
                                      
              
$window->add($fixed);
              
$window->show_all();
         }
         
         
//CONEXÃO VIA SOCKETS
         
function conecta($server, $port)
         {
             
$this->socket = fsockopen($server, $port, $errno, $errstr, 1);
             
             
//CASO DE FALHA NA CONEXÃO
              
if (!$this->socket) 
              { 
                  die(
"$errstr ($errno)
"
);
              }
         }
         
         function 
envia_consulta($nome)
         {
              if (
$this->socket)    
              {
                  
fputs($this->socket, $nome); //ENVIA PARA A PORTA O VALOR DA PESQUISA
                  
$this->recebe_resposta();
              }
              else 
                echo 
"Socket fora do ar!!";
         }
         
         function 
recebe_resposta()
         {
             if (
$this->socket)    
            {
                
$resposta = fgets($this->socket, 37)."
"
;
                echo 
$resposta;
                
$this->textbuffer->set_text("$resposta");
                
$this->input_nome->set_text('');
                
$this->window->set_focus($this->input_nome);            } 
            else 
                echo 
"Socket fora do ar!!";
         }
                
         
//QDO BOTÃO PESQUISAR FOR CLICADO
         
function pesquisa()
         {
             
$this->textbuffer->set_text('');
             
$nome = $this->input_nome->get_text();
             
$this->envia_consulta($nome); //ENVIA O Q FOI DIGITADO NA INPUT P/ FUNÇÃO ENVIA_CONSULTA
         
}
     }
    
     new 
MyClass();
     
Gtk::main();
?>

</code>




Comentários

  Muito bom 

Muito bom, só tenho uma duvida? Ao fazer uns testes mesmo em servidor local a resposta demora muito, o que podemos fazer para agilizar?

  Enviado por Wender Fernandes em 2008-10-01  

 Adicionar Comentário
 login
 Senha
 Título
 Comentário

Livros


  • Artigos

    • Ambiente RAD completo para PHP-GTK
    • Seleção de Texto em um Entry

    Projetos

    • Electronic Manager
    • GTKSMS
    • Apache error log reader
    • Launcher para aplicações PHP-GTK
  • Google

    Parceiros

 
Designed by Wolfgang Bartelme Designed by Wolfgang Bartelme

© 2006 Wordpress Themes | Theme (Not so) Fresh
XHTML CSS

PHP-GTK Brasil