Introdução
Uma dúvida de um aluno da Academia Java me incentivou a dar continuidade ao assunto de programação Java para redes, iniciado em Java e Redes: Consultando um serviço com Socket que mostrava como consultar um serviço do NIST por meio da API de redes da Plataforma Java, este post apresenta a implementação de um
Exemplo
Para a criação de um
Apenas a criação do objeto
ServerFileSocket.java
Segue o código completo da classe que implementa o servidor que responde aos clientes com o arquivo determinado.
Esta classe não está explicada detalhadamente no artigo, porém acredito que o artigo anterior: Java e Redes: Consultando um serviço com Socket, juntamente com este podem esclarecer sobre o funcionamento da classe.
Outro ponto importante, é com relação a porta utilizada, caso a porta 8080 já esteja sendo utilizada, basta alterar a variável
Além disso é possível alterar o arquivo enviado, alterando o valor da variável
Teste se possível em máquinas diferentes, alterando as variáveis indicadas, tente ainda alterar o arquivo enviado.
Até mais!
Marcelo de Castro
Uma dúvida de um aluno da Academia Java me incentivou a dar continuidade ao assunto de programação Java para redes, iniciado em Java e Redes: Consultando um serviço com Socket que mostrava como consultar um serviço do NIST por meio da API de redes da Plataforma Java, este post apresenta a implementação de um
java.net.ServerSocket que responde aos clientes com um determinado arquivo.Exemplo
Para a criação de um
ServerSocket que será responsável por escrever os bytes de um determinado arquivo no canal de comunicação com o cliente, definiremos a porta no construtor, conforme segue:int port = 8080; ServerSocket server = new ServerSocket(8080);
Apenas a criação do objeto
server da classe ServerSocket não permite ainda a comunicação, para tanto é necessário que o ServerSocket passe a aceitar conexões, e isto é feito pelo método accept, este método é bloqueante, ou seja, faz com que o programa fique parado até que o servidor receba uma requisição, e quando isto ocorrer cria um Socket para comunicação; Socket este que tem sua referência armazenada na variável socket, de acordo com a linha apresentada abaixo:Socket socket = server.accept();E então, após uma requisição ser recebida, podemos recuperar o fluxo para escrita no socket, por meio do método
getOutputStream e montar o fluxo de escrita otimizado com uso de um objeto do tipo BufferedOutputStream , conforme trecho de código abaixo:OutputStream socketOutput = socket.getOutputStream(); BufferedOutputStream output = new BufferedOutputStream(socketOutput);Para ler o arquivo determinado criaremos um fluxo de leitura otimizado, conforme segue:
String pathname = "feed.png"; FileInputStream fileInput = new FileInputStream(pathname); BufferedInputStream input = new BufferedInputStream(fileInput);Depois de montado o fluxo de entrada (
input), que lê um determinado arquivo, e o fluxo de saída (output), basta realizar a leitura da entrada e escrever na saída, enquanto existirem bytes a serem lidos, conforme trecho abaixo:int data = 0;
while( (data = input.read()) !=-1){
output.write(data);
}
O método accept está em um laço infinito while(true){} e a forma de interromper a execução do servidor é interromper o processo no console ou na sua IDE preferida, ou ainda determinar a quantidade de vezes que o servidor vai executar o laço.ServerFileSocket.java
Segue o código completo da classe que implementa o servidor que responde aos clientes com o arquivo determinado.
package br.eti.castro.blog.samples.networking;
// imports ocultos
public class ServerFileSocket {
//o tratamento de excessoes foi simplificado (throws UnknownHostException, IOException)
//para simplificar o entendimento do exemplo
public static void main(String[] args) throws IOException {
//declarando de objetos para a leitura do arquivo
String pathname = "feed.png";//pode conter o caminho
BufferedInputStream input = null;
FileInputStream fileInput = null;
//declarando de objetos para a escrita no fluxo do socket
OutputStream socketOutput = null;
BufferedOutputStream output = null;
//Criando um servidor que atendera na porta 8080
int port = 8080;
ServerSocket server = new ServerSocket(port);
while(true){
//O metodo accept faz com que o servidor aguarde uma requisicao
//Quando isto ocorrer cria um Socket para comunicacao
Socket socket = server.accept();
//montando o fluxo de leitura do arquivo otimizado
fileInput = new FileInputStream(pathname);
input = new BufferedInputStream(fileInput);
//montando o fluxo de dados para escrita no socket
socketOutput = socket.getOutputStream();
output = new BufferedOutputStream(socketOutput);
int data = 0;
//lendo o arquivo
while( (data = input.read()) !=-1){
//escrevendo o dado lido no socket
output.write(data);
}
//fechando o fluxo de entrada
input.close();
//fechando o fluxo de saida
output.flush();
output.close();
//fechando o socket
socket.close();
}
}
}
ClientFileSocket.javaEsta classe não está explicada detalhadamente no artigo, porém acredito que o artigo anterior: Java e Redes: Consultando um serviço com Socket, juntamente com este podem esclarecer sobre o funcionamento da classe.
package br.eti.castro.blog.samples.networking;
//imports ocultos
public class ClientFileSocket {
//o tratamento de excessoes foi simplificado (throws UnknownHostException, IOException)
//para simplificar o entendimento do exemplo
public static void main(String[] args) throws UnknownHostException, IOException {
//declarando de objetos para a leitura do fluxo do socket
BufferedInputStream input = null;
InputStream socketInput = null;
//declarando de objetos para a escrita do arquivo
String pathname = "novo.png";
FileOutputStream fileOutput = null;
BufferedOutputStream output = null;
//criando o socket para o localhost na porta 8080
String host = "localhost";
int port = 8080;
Socket socket = new Socket(host, port);
//recuperando o fluxo de dados
socketInput = socket.getInputStream();
//montando o fluxo de leitura do socket otimizado
input = new BufferedInputStream(socketInput);
//montando o fluxo de escrita do arquivo otimizado
fileOutput = new FileOutputStream(pathname);
output = new BufferedOutputStream(fileOutput);
//lendo o socket
int i = 0;
while( (i = input.read()) !=-1){
//escrevendo o arquivo
output.write(i);
}
//fechando o fluxo de entrada
input.close();
//fechando o fluxo de saida
output.flush();
output.close();
//fechando o socket
socket.close();
}
}
O exemplo está preparado para rodar ambas as classes na mesma máquina, pois a classe ClientFileSocket está configurada para procurar o ServerSocket na mesma máquina (host = "localhost"), porém é interessante rodar cada uma das classes em uma máquina diferente, bastando para tanto alterar o valor da variável host.Outro ponto importante, é com relação a porta utilizada, caso a porta 8080 já esteja sendo utilizada, basta alterar a variável
port, que deve ter sempre o mesmo valor na classe ServerFileSocket e na classe ClientFileSocket.Além disso é possível alterar o arquivo enviado, alterando o valor da variável
pathname na classe ServerFileSocket e também o nome em que a classe ClientFileSocket salva o arquivo alterando variável de mesmo nome.Teste se possível em máquinas diferentes, alterando as variáveis indicadas, tente ainda alterar o arquivo enviado.
Até mais!
Marcelo de Castro
http://twitter.com/mcastroinfo
http://www.globalcode.com.br/instrutores/MarceloCastro
Outros posts: http://blog.globalcode.com.br/search/label/MarceloCastro
Comentários