Pular para o conteúdo principal

Interação Cliente/Servidor sem Conexão com Datagramas (Java)

A transmissão sem conexão com datagramas é parecida com a maneira como a correspondência é transportada através do serviço postal. Se uma mensagem grande não couber em um envelope, você a divide em partes de mensagem separadas que você coloca em envelopes separados, numerados seqüencialmente. Cada uma das cartas é, então, remetida ao mesmo tempo. As cartas podem chegar em ordem, fora da ordem, ou não chegar (pouco provável). O receptor monta novamente os pedaços da mensagem na ordem seqüencial antes de tentar dar sentido a mensagem. Se a mensagem é suficientemente pequena para caber em um envelope, não há necessidade de se preocupar com a questão seqüencial.

A classe Servidor
A classe Server_D define dois DatagramPackets que o servidor utiliza para enviar e receber informações e um DatagramSocket que envia e recebe esses pacotes. O construtor para a classe Server_D cria a interface gráfica com o usuário na qual os pacotes de informação serão exibidos. Em seguida, o construtor cria o DatagramSocket em um bloco try. O construtor DatagramSocket recebe um argumento de numero de porta inteiro (5000) para vincular o servidor a uma porta em que o servidor pode receber pacotes de clientes. Os Clientes que enviam pacotes para esse servidor especificam a porta 5000 nos pacotes enviados. O construtor DatagramSocket dispara um SocketException se não conseguir vincular o DatagramSocket a uma porta.
package PKJServer_D;

//pacotes de nucleo do java
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;

//pacotes de extenção
import javax.swing.*;

public class Server_D extends JFrame{
private JTextArea displayArea;
private DatagramPacket sendPacket, receivePacket;
private DatagramSocket socket;

//configura a GUI e o DatagramSocket
public Server_D()
{
super("Servidor");
displayArea = new JTextArea();
getContentPane().add( new JScrollPane( displayArea ), BorderLayout.CENTER );
setSize( 400, 300 );
setVisible( true );

//cria DatagramSocket para enviar e receber pacotes
try
{
socket = new DatagramSocket( 5000 );
}

//processa problemas ocorridos na criação do datagramSocket
catch( SocketException socketException )
{
socketException.printStackTrace();
System.exit( 1 );
}

}//fim do construtor Server_D

//espera que os pacotes cheguem e, depois,
//exibe os dados e ecoa o pacote para o cliente
public void waitForPackets()
{
//repete laço pra sempre
while( true )
{
try
{
//recebe o pacote
byte data[] = new byte[100];
receivePacket = new DatagramPacket( data, data.length );

//espera o pacote
socket.receive( receivePacket );

//processa o pacote
displayPacket();

//ecoa as informações
sendPacketToClient();

}
//processa problemas ocorridos na manipulação do pacote
catch( IOException ioException )
{
displayArea.append( ioException.toString() + "\n" );
ioException.printStackTrace();
}
}//fim do while

//processa problemas
}//fim do metodo waitForPackets

//exibe o conteudo do pacote
private void displayPacket()
{
displayArea.append( "\nPacote Recebido:" +
"\ndo Host: " + receivePacket.getAddress() +
"\nPorta do Host: " + receivePacket.getPort() +
"\nTamanho: " + receivePacket.getLength() +
"\nContendo:\n\t" +
new String( receivePacket.getData(), 0, receivePacket.getLength() )
);
}

//ecoa pacote para o cliente
private void sendPacketToClient() throws IOException
{
displayArea.append( "\n\nEnviando para o Cliente..." );

//cria pacote para enviar
sendPacket = new DatagramPacket( receivePacket.getData(),
receivePacket.getLength(),
receivePacket.getAddress(),
receivePacket.getPort()
);
//envia pacote
socket.send( sendPacket );

displayArea.append( "Pacote Enviado\n" );
displayArea.setCaretPosition( displayArea.getText().length() );
}

//executa o aplicativo
public static void main(String[] args)
{
Server_D application = new Server_D();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
application.waitForPackets();

}

}//fim da classe Server_D

A classe Cliente
A classe Client_D funciona de maneira semelhante a classe Server_D, com a diferença que o cliente envia pacotes apenas quando o usuário digita uma mensagem no JTextField e pressiona a tecla Enter. Quando isso ocorre, o programa chama o método actionPerformed, que converte o String que o usuário digitou no JTextField em um array de byte. È criado um DatagramPacket inicializado com um array de byte, o comprimento do String digitado pelo usuário, o endereço da internet para o qual o pacote deve ser enviado (InetAddress.getLocalHost()) e o numero da porta em que o servidor esta esperando os pacotes.

package PKJClient_D;

//pacotes de nucleo do java
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;

//pacotes de extenção
import javax.swing.*;

public class Client_D extends JFrame{
private JTextField enterField;
private JTextArea displayArea;
private DatagramPacket sendPacket, receivePacket;
private DatagramSocket socket;

//configura a GUI e o DatagramSocket
public Client_D()
{
super( "Cliente" );
Container container = getContentPane();
enterField = new JTextField( "Digite a Mensagem aqui" );
enterField.addActionListener(
new ActionListener()
{
//cria e envia pacote
public void actionPerformed( ActionEvent event )
{
//cria e envia pacote
try
{
displayArea.append( "\nEnviando o Pacote contendo: " +
event.getActionCommand() + "\n");
//obtém mensagem do campo de texto e a converte
//para um array de bytes
String message = event.getActionCommand();
byte data[] = message.getBytes();

//cria sendPacket
sendPacket = new DatagramPacket(
data, data.length, InetAddress.getLocalHost(), 5000 );

//envia pacote
socket.send( sendPacket );

displayArea.append( "Pacote enviado\n" );
displayArea.setCaretPosition( displayArea.getText().length() );
}
//processa problemas ocorridos no criação ou no evento do pacote
catch ( IOException ioException )
{
displayArea.append( ioException.toString() + "\n" );
ioException.printStackTrace();
}
}//fim do método actionPerformed
}//fim da classe interna anônima

);//fim da chamada addActionListener

container.add( enterField, BorderLayout.NORTH );

displayArea = new JTextArea();
container.add( new JScrollPane( displayArea ), BorderLayout.CENTER );
setSize( 400, 300 );
setVisible( true );

//cria DatagramSocket para enviar e receber pacotes
try
{
socket = new DatagramSocket();
}
//captura problemas ocorridos na criação do DAtagramSocket
catch( SocketException socketException )
{
socketException.printStackTrace();
System.exit( 1 );
}
}//fim do construtor Client_D

//espera que os pacotes cheguem do Servidor,
//depois exibe o conteudo dos pacotes
public void waitForPackets()
{
//repete o laço para sempre
while( true )
{
//recebe o pacote e exibe o conteudo
try
{
//configura o pacote
byte data[] = new byte[ 100 ];
receivePacket = new DatagramPacket( data, data.length );

//espera o pacote
socket.receive( receivePacket );

//exibe o conteudo do pacote
displayPacket();
}
//processa problemas ocorridos no recepção ou exibição do pacote
catch( IOException exception )
{
displayArea.append( exception.toString() + "\n" );
exception.printStackTrace();
}
}//fim do while
}//fim do método waitForPackets

//exibe conteudo do receivePacket
private void displayPacket()
{
displayArea.append( "\nPacote Recebido:" +
"\ndo Host: " + receivePacket.getAddress() +
"\nPorta do Host: " + receivePacket.getPort() +
"\nTamanho: " + receivePacket.getLength() +
"\nContendo:\n\t" +
new String( receivePacket.getData(), 0, receivePacket.getLength() )
);
displayArea.setCaretPosition( displayArea.getText().length() );

}

//executa o aplicativo
public static void main(String[] args) {
Client_D application = new Client_D();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
application.waitForPackets();
}
}//fim da classe Client_D

Na imagem a seguir temos ambas aplicações:

Fonte:

Comentários

Mais visitadas

Funções de data Oracle

  Com o Oracle é possível obter uma série de resultados a partir de uma ou mais datas, como por exemplo verificar o último dia do mês ou verificar a quantidade de meses entre duas datas, então vamos a alguns exemplos:   Data atual do sistema: SYSDATE Remover meses de uma data: ADD_MONTHS(SYSDATE, -1) Adicionar meses de uma data: ADD_MONTHS(SYSDATE, +1) Buscar o último dia do mês: LAST_DAY(SYSDATE) Primeiro dia do mês: TRUNC(SYSDATE, ‘MONTH’) Quantidade de meses entre duas datas: MONTHS_BETWEEN(SYSDATE, ‘27/07/1982’) Primeiro dia do ano: TRUNC(SYSDATE, ‘YEAR’) Dias da semana: DECODE( TO_NUMBER( TO_CHAR          (SYSDATE, ‘D’) ) ,1, ‘domingo’ ,2, ‘segunda-feira’ ,3, ‘terça-feira’ ,4, ‘quarta-feira’ ,5, ‘quinta-feira’ ,6, ‘sexta-feira’ ,7,’sábado’ )

Funções de Data e Hora (Delphi)

É muito comum nos depararmos no dia a dia com a necessidade de manipular datas e horas, seja para um calculo de permanência, dias de atraso enfim, é praticamente escapar de alguma situação que necessite desse tipo de controle. Assim como a necessidade e se utilizar algum recurso para manipular as datas e horas de alguma maneira e freqüente, as duvidas de como o faze-lo também é, basta um breve olhar em qualquer fórum especializado e lá está, alguma duvida relacionada, por isso decidi falar um pouco sobre uma unit muito poderosa chamada DateUtils para a manipulação de data e hora, com um grande numero de métodos e classes que facilitam a vida de qualquer um. Alguns exemplos: CompareDate(constA, B: TDateTime): TValueRelationship; Compara apenas a data de dois valores (do tipo TDateTime) retornando: LessThanValue O primeiro valor é menor que o segundo EqualsValue Os valores são iguais GreaterThanValue O primeiro valor é maior que o segundo CompareDateTime(const A, B: TD

Como Verificar se um Objeto Existe (Delphi)

Em alguns momentos surge a necessidade de verificar se um determinado objeto existe, ou seja se já foi criado, principalmente quando se trabalha com criação dinâmica em tempo de execução, então vamos ao exemplo: - Vamos criar uma variável, um vetor do tipo caixa de texto: var Minha_caixa : array of TEdit; - Em seguida definir o tamanho desse vetor, no caso será dez: setLength(Minha_caixa, 10) - Agora iremos criar nossa caixa de texto: // lembrando que o vetor inicia em zero // logo o índice final é o tamanho total - 1 for vl_i := 0 to Length(Minha_caixa) -1 do begin Minha_caixa[vl_i] := TEdit.Create(self); with Minha_caixa[vl_i] do begin Parent := Self; Name := 'Caixa_N'+IntToStr(vl_i); Text := 'Esta é a '+IntToStr(vl_i)+' º caixa !'; ReadOnly := true; Height := 21; Width :=