Neste artigo vamos ficar a conhecer o suporte que Java oferece para a utilização do mecanismo de comunicação Socket, o mecanismo mais utilizado para a comunicação entre aplicações.Java permite o uso de socktes pelos seguintes modos utilização.
- Modo Orientado à Conexão - Funciona com o protocolo TCP.
- Modo Orientado ao Datagrama - Funciona com o protocolo UDP.
Ambos os modos funcionam sobre o protocolo IP(Internet Protocol).
Cada um destes modos tem a sua utilidade, vantagens e desvantagens na sua utilização.Modo Orientado á Conexão (TPC/IP).
- Serviços confiáveis , sem perda de dados na rede e ordem dos pacotes.
- Possibilidade de usar DataStreams.
- É mais lento que o modo orientado ao datagrama.
- O comportamento do servidor é diferente do comportamento do cliente.Modo Orientado ao
Datagrama (UDP/IP).
- É bastante mais rápido que o modo orientado a conexão.
- Serviços não confiáveis, mensagens perdidas na rede e perda da ordem das mensagens.
- Cada mensagem é um datagrama : [Remetente, Destinatário, Conteúdo].
Devido a uma maior utilização e estabilidade iremos apenas analisar e implementar o Modo Orientado à Conexão - TCP/IP.
Sockets TCP/IP
O processo de comunicação entre sockets TCP/IP, de uma forma simples, o servidor escolhe uma porta e aguarda conexões a essa porta, o cliente deve conter as seguintes informações :
- Endereço do Servidor (HOST).
- A porta usada pelo servidor(PORT).
Com essa informação o cliente solicita uma conexão ao servidor (Figura 1).
Se após o pedido de conexão não ocorrer nenhum problema, o servidor aceita a conexão gerando um socket numa porta do servidor, o que vai criar um canal de comunicação entre o ciente e o servidor (Figura 2).
Por norma o servidor funciona em ciclo (loop) esperando por novas conexões e criando sockets para solicitações de clientes.
Em seguida iremos ver as acções necessárias para implementar comunicações sobre TCP através de um socket cliente e um socket servidor.
Socket Client
1 – Abrir Conexão.
import java.io.*;
import java.net.*;
//Conectar ao servidor localhost na porta 8080.
Socket client = new Socket("127.0.0.1",8080);
2 – Obter Streams de entrada e saída para comunicação com o servidor.
//Cria um canal para receber dados.
DataInputStream in = new DataInputStream(client.getInputStream());
//Cria um canal para enviar dados.
DataOutputStream out = new DataOutputStream(client.getOutputStream());
3 – Realizar a comunicação com o servidor.
//Envia o inteiro 3000.
out.writeInt(3000);
//Envia a String “Olá - Socket Cliente.”.
out.writeUTF("Olá - Socket Cliente.");
//Espera pelo recebimento de um inteiro.
int valor = in.readInt();
//Espera pelo recebimento de uma String.
String texto = in.readUTF();
4 – Fechar as Streams e a conexão.
//Fecha o canal de entrada.
in.close();
//Fecha o canal de saída.
out.close();
//Fecha o Socket.
client.close();
Socket Servidor
1 – Criar Socket Server.
import java.io.*;
import java.net.*;
//Cria um socket servidor na porta 8080.
ServerSocket serveer = new ServerSocket(8080);
2 – Aguardar Conexões.
//O método accept retorna um socket para comunicação com o proximo cliente.
Socket sock = server.accept();
3 – Obter Streams de entrada e saída para comunicação com o cliente.
//Cria um canal para receber dados.
DataInputStream in = new DataInputStream(sock.getInputStream());
//Cria um canal para enviar dados.
DataOutputStream out = new DataOutputStream(sock.getOutputStream());
4 – Realizar a comunicação com o cliente.
//Espera pelo recebimento de um inteiro.
int valor = in.readInt();
//Espera pelo recebimento de uma String.
String texto = in.readUTF();
//Envia o inteiro 6000.
out.writeInt(6000);
//Envia a String “Olá - Socket Servidor.”.
out.writeUTF("Olá - Socket Servidor.");
5 – Fechar Streams e socket cliente.
//Fecha o canal de entrada.
in.close();
//Fecha o canal de saída.
out.close();
//Fecha o Socket que está a atender o cliente.
sock.close();
6 – Fechar o socket Servidor.
//Fecha o servidor.
server.close();
Em seguida podemos ver as classes Cliente e Servidor completamente implementadas.
Classe Cliente
1 import java.io.*;
2 import java.net.*;
3
4 public class Cliente{
5 public Socket client;
6 public DataInputStream in;
7 public DataOutputStream out;
8
9 public Cliente(){
10 try{
11 this.client = new Socket("127.0.0.1",8080);
12 this.in = new DataInputStream(client.getInputStream());
13 this.out = new DataOutputStream(client.getOutputStream());
14 }
15 catch(IOException e){
16 System.out.println(e.getMessage());
17 }
18 }
19
20 public static void main(String args[]){
21 try{
22 Cliente cli = new Cliente();
23 cli.out.writeInt(3000);
24 cli.out.writeUTF("Olá - Socket Cliente.");
25 int valor = cli.in.readInt();
26 String texto = cli.in.readUTF();
27 System.out.println(valor);
28 System.out.println(texto);
29 cli.in.close();
30 cli.out.close();
31 cli.client.close();
32 }
33 catch(IOException e){
34 System.out.println(e.getMessage());
35 }
36 }
37 }
Classe Servidor
1 import java.io.*;
2 import java.net.*;
3
4 public class Servidor{
5 public ServerSocket server;
6 public Socket sock;
7 public DataInputStream in;
8 public DataOutputStream out;
9
10 public Servidor(){
11 try{
12 this.server = new ServerSocket(8080);
13 this.sock = this.server.accept();
14 this.in = new DataInputStream(sock.getInputStream());
15 this.out = new DataOutputStream(sock.getOutputStream());
16 }
17 catch(IOException e){
18 System.out.println(e.getMessage());
19 }
20 }
21
22 public static void main(String args[]){
23 try{
24 Servidor serv = new Servidor();
25 int valor = serv.in.readInt();
26 String texto = serv.in.readUTF();
27 System.out.println(valor);
28 System.out.println(texto);
29 serv.out.writeInt(6000);
30 serv.out.writeUTF("Olá - Socket Servidor.");
31 serv.in.close();
32 serv.out.close();
33 serv.sock.close();
34 serv.server.close();
35 }
36 catch(IOException e){
37 System.out.println(e.getMessage());
38 }
39 }
40 }
Este artigo foi originalmente escrito por Fábio Correira (magician) para a 6ª Edição da Revista PROGRAMAR