Java - Redes
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 uns aos outros usando 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 concentrem na solução do 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 uma comunicação confiável entre dois aplicativos. O TCP é normalmente usado pelo 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 dá uma boa compreensão sobre os dois seguintes assuntos -
-
Programação de soquete − Este é o conceito mais utilizado em Networking e foi explicado em muito detalhe.
-
Processamento de URL − Isso seria coberto separadamente. Clique aqui para saber mais 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 socket no final da comunicação. O cliente e o servidor agora podem se comunicar escrevendo e lendo no soquete.
A classe java.net.Socket representa um soquete, e a classe java.net.ServerSocket fornece um mecanismo para o programa servidor escutar 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, indicando 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 especificada.
-
Após o servidor estar 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 possui 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 soquete tem 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 em ambos os fluxos ao mesmo tempo. A seguir estão as classes úteis que fornecem um conjunto completo de métodos para implementar soquetes.
Métodos da classe ServerSocket
O java.net.ServerSocket A classe é usada por aplicativos de servidor para obter uma porta e ouvir solicitações de clientes.
A classe ServerSocket tem quatro construtores -
| Nº Sr. | Método e descrição |
|---|---|
| 1 | public ServerSocket(int port) lança 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) lança IOException Semelhante ao construtor anterior, o parâmetro backlog especifica quantos clientes de entrada armazenar em uma fila de espera. |
| 3 | public ServerSocket(porta int, backlog int, endereço InetAddress) lança IOException Semelhante ao construtor anterior, o parâmetro InetAddress especifica o endereço IP local ao qual associar. O InetAddress é usado para servidores que podem ter vários endereços IP, permitindo que o servidor especifique em quais de seus endereços IP aceitar solicitações de clientes. |
| 4 | public ServerSocket() lança 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, isso significa que seu aplicativo foi vinculado com êxito à porta especificada e está pronto para solicitações do cliente.
A seguir estão alguns dos métodos comuns da classe ServerSocket -
| Nº Sr. | Método e descrição |
|---|---|
| 1 | public int getLocalPort() Retorna a porta na qual 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() lança IOException Aguarda um cliente de entrada. Esse método é bloqueado 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 argumentos. |
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. Uma conexão TCP agora existe entre o cliente e o servidor, e a comunicação pode começar.
Métodos de classe de soquete
O java.net.Socket A classe 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 a partir do valor de retorno do método accept().
A classe Socket tem cinco construtores que um cliente usa para se conectar a um servidor -
| Nº Sr. | Método e descrição |
|---|---|
| 1 | public Socket(String host, int port) lança 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(host InetAddress, porta int) lança IOException Esse método é idêntico ao construtor anterior, exceto que o host é indicado por um objeto InetAddress. |
| 3 | public Socket(String host, int port, InetAddress localAddress, int localPort) lança 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) lança IOException. Esse método é idêntico ao construtor anterior, exceto que o host é indicado por um objeto InetAddress em vez de um String. |
| 5 | Soquete público() Cria um soquete desconectado. Use o método connect() para conectar este soquete a um servidor. |
Quando o construtor Socket retorna, ele não instancia simplesmente 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 invocados pelo cliente e pelo servidor.
| Nº Sr. | Método e descrição |
|---|---|
| 1 | public void connect(SocketAddress host, int timeout) lança IOException Este método conecta o soquete ao host especificado. Esse método é necessário apenas quando você instancia o Socket usando o construtor sem argumento. |
| 2 | public InetAddress getInetAddress() Esse método retorna o endereço do outro computador ao qual esse 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 | público SocketAddress getRemoteSocketAddress() Retorna o endereço do soquete remoto. |
| 6 | public InputStream getInputStream() lança 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() lança 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() lança 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
Essa classe representa um endereço IP (Internet Protocol). Aqui estão os seguintes métodos úteis que você precisaria ao fazer a programação de soquete -
| Nº Sr. | Método e descrição |
|---|---|
| 1 | estático InetAddress getByAddress(byte[] addr) Retorna um objeto InetAddress dado o endereço IP bruto. |
| 2 | estático InetAddress getByAddress(String host, byte[] addr) Cria um InetAddress com base no nome do host e no endereço IP fornecidos. |
| 3 | estático 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 | estático InetAddress InetAddress getLocalHost() Retorna o host local. |
| 7 | String toString() Converte este endereço IP em uma String. |
Exemplo de cliente de soquete
O GreetingClient a seguir é um programa cliente que se conecta a um servidor usando um soquete, envia uma saudação e 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 programa GreetingServer a seguir é um exemplo de um aplicativo de servidor que usa a classe Socket para escutar 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 inicie o servidor da seguinte forma -
$ java GreetingServer 6066 Waiting for client on port 6066...
Verifique o programa cliente da seguinte forma -
Saída
$ 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!
Java