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

Aplicação Flask usando Nginx e Gunicorn

Aplicação Flask usando Nginx e Gunicorn Se você já desenvolveu uma aplicação Flask básica, sabe que o servidor de desenvolvimento embutido não é ideal para produção. Ele não é projetado para lidar com altos volumes de tráfego ou conexões simultâneas. Para tornar sua aplicação Flask mais robusta e pronta para produção, podemos usar o Gunicorn como servidor de aplicação e o Nginx como proxy reverso. Neste artigo, vamos adaptar o exemplo anterior ( Criando uma Aplicação CRUD com Flask, PostgreSQL e Docker ) para incluir o Nginx e o Gunicorn. O que são Nginx e Gunicorn? Gunicorn O Gunicorn (Green Unicorn) é um servidor de aplicação WSGI que roda aplicações Python como o Flask. Ele é eficiente e simples de configurar, lidando com múltiplas requisições ao mesmo tempo, algo que o servidor embutido do Flask não faz bem. Nginx O Nginx é um servidor web que atua como um proxy reverso. Ele recebe requisições HTTP e as encaminha ao Gunicorn. Além disso, o Nginx pode: Servir arquivos ...

Criando sua Primeira Aplicação Web com Python e Docker

  Criando sua Primeira Aplicação Web com Python e Docker Hoje vamos fazer algo prático: criar uma aplicação web simples em Python usando Flask e executá-la dentro de um contêiner Docker. Se você não sabe exatamente o que é Docker ou Flask, não se preocupe! Vou explicar tudo de forma simples para que você consiga acompanhar sem problemas. O que é Docker? Docker é uma ferramenta que permite empacotar aplicações e suas dependências em contêineres, garantindo que elas funcionem da mesma forma em qualquer ambiente. Em outras palavras, com o Docker, você cria um ambiente isolado e padronizado para rodar suas aplicações. Como instalar o Docker Acesse o site oficial do Docker . Baixe e instale a versão apropriada para o seu sistema operacional (Windows, macOS ou Linux). Após a instalação, verifique se está tudo funcionando abrindo um terminal e executando: docker --version Se o Docker estiver instalado corretamente, ele vai exibir a versão instalada. O que é Flask? Flask é um m...

Criando uma Aplicação CRUD com Flask, PostgreSQL e Docker

Criando uma Aplicação CRUD com Flask, PostgreSQL e Docker Neste guia, vamos criar uma aplicação básica que acessa um banco de dados PostgreSQL e realiza operações CRUD (Create, Read, Update, Delete). Vamos usar Flask e executar tudo com Docker. Sem estilos ou extras, apenas o essencial. Estrutura do Projeto crud-app/ |-- app/ | |-- app.py | |-- templates/ | | |-- index.html | | |-- edit.html |-- Dockerfile |-- requirements.txt |-- docker-compose.yml Passo 1: Dependências Crie um arquivo requirements.txt com as seguintes linhas: Flask==2.2.2 Flask-SQLAlchemy==3.0.2 psycopg2-binary==2.9.3 Werkzeug==2.2.2 Passo 2: Aplicação Flask Arquivo app/app.py : from flask import Flask, render_template, request, redirect, url_for from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # Configuração do banco de dados app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password@db:5432/crud_db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db...