CAPÍTULO 6
Programação visual com Software Livre
EDIT LIN EDITORIAL S.L,  dos autores  Daniel Campos Fernández e José Luis Redrejo.  Prólogo de Benoit Minisini

<< Anterior Próximo >>


6.5 UDP




O trabalho com UDP a princípio pode resultar algo mais complexo para o principiante. Em UDP não existe uma conexão entre cliente e servidor, tão pouco chegam dados por uma porta, ou envia-se, porem sem conhecer se do outro lado há alguem a escuta. Assim não existe servidores ou cliente realmente, ainda que na prática faremos esta distinção na hora de desenhar uma aplicação servidora ou cliente. Já que não existe conexão, cada pacote identifica-se com seu endereço IP e porta de origem, e este dado será essencial na hora de devolver uma resposta ao lado remoto.

Gambas da acesso ao protocolo UDP através dos objetos de classe UdpSocket, que servem tanto para criar programas servidores como para programas cliente. Para iniciar o trabalho com um objeto desta classe, temos de chamar o método Bind, no qual temos de indicar a porta local a que estará ligado. Os servidores haverão de estar unidos a uma porta concreta definida, e os clientes a qualquer porta, já que o interesse do cliente é enviar dados a um servidor remoto em uma dada porta, independentemente da porta local que emprega para isso.

UdpSocket proporciona várias propriedades para identificar os pacotes. Quando chega um pacote ao socket procedente de uma localização remota, gera um evento Read e nele podemos consultar o IP de procedência com a propriedade SourcePort. Para enviar um pacote a um sistema remoto, temos de lembrar previamente o valor das propriedades TargetHost, com o IP de destino, e TargetPort, com a porta de destino.

Criaremos um servidor muito simples: atenderemos a porta UDP 3319, recebe os dados e envia como resposta o texto ADIOS ao host que enviou o pacote. Para implementa-lo criaremos um projeto de console chamado MeuServidorUDP,  com um módulo ModMain e uma referência ao componente gb.net. O código é o seguinte:


' Gambas module file


PRIVATE Meuservidor AS UdpSocket


PUBLIC SUB Servidor_Read()

DIM sCad AS String


READ #Meuservidor, sCad, Lof(Meuservidor)


Meuservidor.TargetHost = Meuservidor.SourceHost

Meuservidor.TargetPort = Meuservidor.SourcePort


WRITE #Meuservidor, "ADEUS", 5


END


PUBLIC SUB Main()


Meuservidor = NEW UdpSocket AS "Servidor"

Meuservidor.Bind(3319)


END

Dispomos de um objeto da classe Udpsocket que criamos na função Main. Fazemos uma chamada a Bind para enlaça-lo com a porta UDP 3319. Como no caso do servidor TCP, o interpretador Gambas fica a espera de algum evento no socket. Quando chega um pacote de dados, se lê como no caso dos sockets TCP, fazendo uso da instrução READ, a seguir colocamos as propriedades TargetHost e TargetPort com os valores correspondentes a procedência do pacote de dados, e enviamos a cadeia ADEUS, que chegará ao host especificado. Quanto a parte cliente, trata-se de outro programa de console que chamaremos MeuClienteUDP, com uma referência ao componente gb.net, e que terá um único módulo chamado ModMain. O cliente tratará de conectar com o servidor, enviará uma cadeia OLA e recebe uma cadeia completa ADEUS, encerra o socket e acabará seu funcionamento.

' Gambas module file


PRIVATE MeuCliente AS UdpSocket

PRIVATE Buffer AS String


PUBLIC SUB Cliente_read()

DIM sBuf AS String


READ #MeuCliente, sBuf, Lof(MeuCliente)

IF Buffer = "ADEUS" THEN CLOSE #MeuCliente


END


PUBLIC SUB Main()


MeuCliente = NEW UdpSocket AS "Cliente"

MeuCliente.Bind(0)

MeuCliente.TargetHost = "127.0.0.1"

MeuCliente.TargetPort = "3319"

WRITE #MeuCliente, "OLA", 4


END
FALTA A PAGINA 216

O controle DnsCliente receberá o nome Cliente em nosso formulário, e a propriedade Async do cliente DNS deve ficar como FALSE.

Estes controles especiais (DnsCliente, Socket, etc.) não são visíveis em tempo de execução, nem são realmente controles, mas são adicionados ao formulário como controles normais para facilitar o trabalho ao criar programas gráficos. O objeto DnsCliente, em nosso caso chamado Cliente, cria-se ao desenvolver o formulário e existe até que se destrua ao encerra-lo ou aplicar o método Delete nesse formulário.
 Próximo >> Próximo >>
O aspecto do desenho será similar ao da Figura 8. Figura 7
Figura 8. Formulário FMain.

' Gambas class file


PUBLIC SUB BtnToIp_Click()


Cliente.HostName = TxtHost.Text

Cliente.GetHostIP()

Message.Info("IP: " & Cliente.HostIP)  


END


PUBLIC SUB BtnToName_Click()


Cliente.HostIP = TxtHost.Text

Cliente.GetHostName()

Message.Info("Nome: " & Cliente.HostName)


END

No primeiro caso, será preenchida a propriedade HostName com o nome do host que desejamos resolver; e chama o método GetHostIP() e depois lemos o IP desse host recém obtido com o valor da propriedade HostIP.

No segundo caso é exatamente ao contrário: preenchemos a propriedade HostIP com o IP que foi escrito pelo usuário na caixa de texto; chamamos o método GetHostName() o lemos e mostramos o valor da propriedade HostName que obtivemos.

Em ambos os casos, se a resolução falha, a ler (HostIP no primeiro caso e HostName no segundo) ficará em branco. Também podemos controlar o estado de erro com a propriedade Status. Se vale zero, a resolução terminou corretamente; se tiver um valor menor que zero, houve um erro, não se encontrou o IP ou o nome do host.

DnsCliente também permite o trabalho em modo assíncrono. Em ocasiões, uma resolução

pode demorar bastante tempo, no qual a interface do usuário fica bloqueada trabalhando em modo síncrono

Para ativar o modo assíncrono, devemos por a propriedade Async do cliente DNS como TRUE. Isto também requer modificar o código. Já não podemos chamar o método GetHostIP() ou GetHostName() e imediatamente ler o valor das propriedades HostName e HostIp respectivamente, já que enquanto o código do programa principal está executando, o cliente DNS está trabalhando internamente. Temos duas opções: a primeira é esperar o evento Finished, que dispara ao acabar o processo; e o segundo é testar o estado da propriedade Status, que valerá um número maior que zero enquanto o processo está em curso, zero quando finaliza com exito ou um valor menor que zero se houver um erro.

Este ´e um pequeno exemplo modificando o código inicial para trabalhar no modo assíncrono. Se testarmos em um loop o estado da propriedade Status, repetindo-se enquanto é maior que zero. Nesse loop poderíamos, por exemplo, controlar a pulsação de um botão Cancelar para abortar o processo.











 

<< Anterior Próximo >>

HOME
                 


Cópia literal

Extraído do livro “GAMBAS, programação visual com software Livre”, da editora EDIT LIN EDITORIAL S.L,  dos autores  Daniel Campos Fernández e José Luis Redrejo. Prólogo de Benoit Minisini

LICENSA DESTE DOCUMENTO


É permitido a cópia e distribuição da totalidade ou parte desta obra sem fins lucrativo. Toda cópia total ou parcial devera expressar o nome do autor e da editora e incluir esta mesma licença, adicionando se é uma cópia literal “Cópia literal”. Se é autorizada a modificação e tradução da obra  sem fins lucrativo sempre se deve constar na obra resultante  a modificação o nome da obra original o autor da obra original e o nome da editora e a obra resultante também deverá ser livremente reproduzida, distribuída, ao publico e transformada em termos similares ao exposto nesta licença.

Tradução

Cientista
 (Antonio Sousa)