Java - Rede

O termo programação de rede refere-se a escrever programas que são executados em vários dispositivos (computadores), nos quais os dispositivos estão todos conectados entre si por meio de uma rede.

O pacote java.net das APIs J2SE contém uma coleção de classes e interfaces que fornecem os detalhes de comunicação de baixo nível, permitindo que você escreva programas que se concentram em resolver o problema em questão.

O pacote java.net fornece suporte para os dois protocolos de rede comuns -

  • TCP- TCP significa Transmission Control Protocol, que permite a comunicação confiável entre dois aplicativos. O TCP é normalmente usado no protocolo da Internet, conhecido como TCP / IP.

  • UDP - UDP significa User Datagram Protocol, um protocolo sem conexão que permite que pacotes de dados sejam transmitidos entre aplicativos.

Este capítulo fornece uma boa compreensão sobre os dois assuntos a seguir -

  • Socket Programming - Este é o conceito mais amplamente utilizado em Redes e foi explicado em detalhes.

  • URL Processing- Isso seria coberto separadamente. Clique aqui para aprender sobre Processamento de URL na linguagem Java.

Programação de soquete

Os soquetes fornecem o mecanismo de comunicação entre dois computadores usando TCP. Um programa cliente cria um soquete em sua extremidade da comunicação e tenta conectar esse soquete a um servidor.

Quando a conexão é feita, o servidor cria um objeto de soquete em sua extremidade da comunicação. O cliente e o servidor agora podem se comunicar gravando e lendo no soquete.

A classe java.net.Socket representa um soquete, e a classe java.net.ServerSocket fornece um mecanismo para o programa do servidor escutar os clientes e estabelecer conexões com eles.

As etapas a seguir ocorrem ao estabelecer uma conexão TCP entre dois computadores usando soquetes -

  • O servidor instancia um objeto ServerSocket, denotando em qual número de porta a comunicação deve ocorrer.

  • O servidor invoca o método accept () da classe ServerSocket. Este método espera até que um cliente se conecte ao servidor na porta fornecida.

  • Depois que o servidor está esperando, um cliente instancia um objeto Socket, especificando o nome do servidor e o número da porta à qual se conectar.

  • O construtor da classe Socket tenta conectar o cliente ao servidor especificado e ao número da porta. Se a comunicação for estabelecida, o cliente agora tem um objeto Socket capaz de se comunicar com o servidor.

  • No lado do servidor, o método accept () retorna uma referência a um novo soquete no servidor que está conectado ao soquete do cliente.

Depois que as conexões são estabelecidas, a comunicação pode ocorrer usando fluxos de E / S. Cada socket possui um OutputStream e um InputStream. O OutputStream do cliente está conectado ao InputStream do servidor e o InputStream do cliente está conectado ao OutputStream do servidor.

O TCP é um protocolo de comunicação bidirecional, portanto, os dados podem ser enviados pelos dois fluxos ao mesmo tempo. A seguir estão as classes úteis que fornecem um conjunto completo de métodos para implementar sockets.

Métodos de classe ServerSocket

o java.net.ServerSocket classe é usada por aplicativos de servidor para obter uma porta e ouvir os pedidos do cliente.

A classe ServerSocket tem quatro construtores -

Sr. Não. Método e Descrição
1

public ServerSocket(int port) throws IOException

Tenta criar um soquete de servidor vinculado à porta especificada. Uma exceção ocorre se a porta já estiver vinculada por outro aplicativo.

2

public ServerSocket(int port, int backlog) throws IOException

Semelhante ao construtor anterior, o parâmetro backlog especifica quantos clientes de entrada armazenar em uma fila de espera.

3

public ServerSocket(int port, int backlog, InetAddress address) throws IOException

Semelhante ao construtor anterior, o parâmetro InetAddress especifica o endereço IP local para vincular. O InetAddress é usado para servidores que podem ter vários endereços IP, permitindo ao servidor especificar em qual de seus endereços IP aceitará as solicitações do cliente.

4

public ServerSocket() throws IOException

Cria um soquete de servidor não acoplado. Ao usar esse construtor, use o método bind () quando estiver pronto para vincular o soquete do servidor.

Se o construtor ServerSocket não lançar uma exceção, significa que seu aplicativo foi vinculado com êxito à porta especificada e está pronto para as solicitações do cliente.

A seguir estão alguns dos métodos comuns da classe ServerSocket -

Sr. Não. Método e Descrição
1

public int getLocalPort()

Retorna a porta em que o soquete do servidor está escutando. Este método é útil se você passou 0 como o número da porta em um construtor e deixou o servidor encontrar uma porta para você.

2

public Socket accept() throws IOException

Espera por um cliente de entrada. Este método bloqueia até que um cliente se conecte ao servidor na porta especificada ou o soquete expire, assumindo que o valor de tempo limite foi definido usando o método setSoTimeout (). Caso contrário, este método bloqueia indefinidamente.

3

public void setSoTimeout(int timeout)

Define o valor de tempo limite para quanto tempo o soquete do servidor espera por um cliente durante o accept ().

4

public void bind(SocketAddress host, int backlog)

Vincula o soquete ao servidor e porta especificados no objeto SocketAddress. Use este método se você tiver instanciado o ServerSocket usando o construtor sem argumento.

Quando o ServerSocket invoca accept (), o método não retorna até que um cliente se conecte. Depois que um cliente se conecta, o ServerSocket cria um novo Socket em uma porta não especificada e retorna uma referência a esse novo Socket. Agora existe uma conexão TCP entre o cliente e o servidor e a comunicação pode começar.

Métodos de classe de soquete

o java.net.Socketclasse representa o soquete que o cliente e o servidor usam para se comunicarem. O cliente obtém um objeto Socket instanciando um, enquanto o servidor obtém um objeto Socket do valor de retorno do método accept ().

A classe Socket tem cinco construtores que um cliente usa para se conectar a um servidor -

Sr. Não. Método e Descrição
1

public Socket(String host, int port) throws UnknownHostException, IOException.

Este método tenta se conectar ao servidor especificado na porta especificada. Se esse construtor não lançar uma exceção, a conexão será bem-sucedida e o cliente será conectado ao servidor.

2

public Socket(InetAddress host, int port) throws IOException

Este método é idêntico ao construtor anterior, exceto que o host é denotado por um objeto InetAddress.

3

public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException.

Conecta-se ao host e porta especificados, criando um soquete no host local no endereço e porta especificados.

4

public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException.

Este método é idêntico ao construtor anterior, exceto que o host é denotado por um objeto InetAddress em vez de um String.

5

public Socket()

Cria um soquete não conectado. Use o método connect () para conectar este socket a um servidor.

Quando o construtor Socket retorna, ele não apenas instancia um objeto Socket, mas na verdade tenta se conectar ao servidor e à porta especificados.

Alguns métodos de interesse na classe Socket estão listados aqui. Observe que tanto o cliente quanto o servidor têm um objeto Socket, portanto, esses métodos podem ser chamados tanto pelo cliente quanto pelo servidor.

Sr. Não. Método e Descrição
1

public void connect(SocketAddress host, int timeout) throws IOException

Este método conecta o soquete ao host especificado. Este método é necessário apenas quando você instancia o Socket usando o construtor sem argumento.

2

public InetAddress getInetAddress()

Este método retorna o endereço do outro computador ao qual este soquete está conectado.

3

public int getPort()

Retorna a porta à qual o soquete está vinculado na máquina remota.

4

public int getLocalPort()

Retorna a porta à qual o soquete está vinculado na máquina local.

5

public SocketAddress getRemoteSocketAddress()

Retorna o endereço do soquete remoto.

6

public InputStream getInputStream() throws IOException

Retorna o fluxo de entrada do soquete. O fluxo de entrada é conectado ao fluxo de saída do soquete remoto.

7

public OutputStream getOutputStream() throws IOException

Retorna o fluxo de saída do soquete. O fluxo de saída é conectado ao fluxo de entrada do soquete remoto.

8

public void close() throws IOException

Fecha o soquete, o que faz com que este objeto Socket não seja mais capaz de se conectar novamente a qualquer servidor.

Métodos de classe InetAddress

Esta classe representa um endereço de protocolo da Internet (IP). Aqui estão os seguintes métodos úteis que você precisa ao fazer a programação de socket -

Sr. Não. Método e Descrição
1

static InetAddress getByAddress(byte[] addr)

Retorna um objeto InetAddress dado o endereço IP bruto.

2

static InetAddress getByAddress(String host, byte[] addr)

Cria um InetAddress com base no nome do host e endereço IP fornecidos.

3

static InetAddress getByName(String host)

Determina o endereço IP de um host, dado o nome do host.

4

String getHostAddress()

Retorna a string do endereço IP na apresentação textual.

5

String getHostName()

Obtém o nome do host para este endereço IP.

6

static InetAddress InetAddress getLocalHost()

Retorna o host local.

7

String toString()

Converte este endereço IP em uma String.

Exemplo de cliente de soquete

O seguinte GreetingClient é um programa cliente que se conecta a um servidor usando um soquete e envia uma saudação e, em seguida, aguarda uma resposta.

Exemplo

// File Name GreetingClient.java
import java.net.*;
import java.io.*;

public class GreetingClient {

   public static void main(String [] args) {
      String serverName = args[0];
      int port = Integer.parseInt(args[1]);
      try {
         System.out.println("Connecting to " + serverName + " on port " + port);
         Socket client = new Socket(serverName, port);
         
         System.out.println("Just connected to " + client.getRemoteSocketAddress());
         OutputStream outToServer = client.getOutputStream();
         DataOutputStream out = new DataOutputStream(outToServer);
         
         out.writeUTF("Hello from " + client.getLocalSocketAddress());
         InputStream inFromServer = client.getInputStream();
         DataInputStream in = new DataInputStream(inFromServer);
         
         System.out.println("Server says " + in.readUTF());
         client.close();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Exemplo de servidor de soquete

O seguinte programa GreetingServer é um exemplo de um aplicativo de servidor que usa a classe Socket para ouvir clientes em um número de porta especificado por um argumento de linha de comando -

Exemplo

// File Name GreetingServer.java
import java.net.*;
import java.io.*;

public class GreetingServer extends Thread {
   private ServerSocket serverSocket;
   
   public GreetingServer(int port) throws IOException {
      serverSocket = new ServerSocket(port);
      serverSocket.setSoTimeout(10000);
   }

   public void run() {
      while(true) {
         try {
            System.out.println("Waiting for client on port " + 
               serverSocket.getLocalPort() + "...");
            Socket server = serverSocket.accept();
            
            System.out.println("Just connected to " + server.getRemoteSocketAddress());
            DataInputStream in = new DataInputStream(server.getInputStream());
            
            System.out.println(in.readUTF());
            DataOutputStream out = new DataOutputStream(server.getOutputStream());
            out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress()
               + "\nGoodbye!");
            server.close();
            
         } catch (SocketTimeoutException s) {
            System.out.println("Socket timed out!");
            break;
         } catch (IOException e) {
            e.printStackTrace();
            break;
         }
      }
   }
   
   public static void main(String [] args) {
      int port = Integer.parseInt(args[0]);
      try {
         Thread t = new GreetingServer(port);
         t.start();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Compile o cliente e o servidor e, em seguida, inicie o servidor da seguinte forma -

$ java GreetingServer 6066
Waiting for client on port 6066...

Verifique o programa cliente da seguinte forma -

Resultado

$ java GreetingClient localhost 6066
Connecting to localhost on port 6066
Just connected to localhost/127.0.0.1:6066
Server says Thank you for connecting to /127.0.0.1:6066
Goodbye!