Pular para o conteúdo principal

Java e Redes: Implementando um ServerSocket

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 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.java

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.

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

Postagens mais visitadas deste blog

10 reasons why we love JSF

1. One-slide technology: it's so simple that I can explain basic JSF with one slide. 2. Easy to extend: components, listeners, render kit, Events, Controller, etc. 3. Real-world adoption: JBoss, Exadel, Oracle, IBM, ... 4. Architecture model: you can choose between more than 100 different architecture. 5. Open-mind community: using JSF you are going to meet very interesting people. 6. We are using JSF the last 5 years and we found very good market for JSF in Brazil 7. Progress: look to JSf 1.1 to JSF 1.2, JSF 1.2 to JSF 2.0. People are working really hard! 8. Many professionals now available 9. It's a standard. It's JCP. Before complain, report and help! 10. Ed Burns, spec leader, is an old Globalcode community friend! EXTRA: My wife is specialist in JSF. She's my F1 for JSF :) Nice job JSF community! -Vinicius Senger

NIO.2 do Java 7: uma nova API do Java para file system

Uma das novidades mais importantes e aguardadas do Java 7 foi a NIO.2, a nova API para a manipulação I/O com Java. A NIO.2, também conhecida como JSR 203 , disponibiliza um conjunto de novos componentes, projetados para melhorar caracterísiticas de I/O com Java como por exemplo: uma nova API para o acesso e manipulação de conteúdo do file system (sistema de arquivos); outra API para operações assíncronas com I/O; e a atualização da API para comunicação via sockets ( channel sockets ).   O Java, antes da versão 7, tratava a manipulação do sistema de arquivos de forma primitiva. O programador tinha de trabalhar com a classe File para representar arquivos e/ou diretórios, com um número escasso de funcionalidades. Uma operação simples como copiar um arquivo demandava um código relativamente grande. Outras funcionalidades triviais, como por exemplo o uso de links simbólicos, não eram suportadas. Esses são alguns dos motivos para justificar o uso de bibliotecas terceiras...

TDC ONLINE: SUA PLATAFORMA DE PALESTRAS GRAVADAS DO TDC DISPONÍVEL

Além do conteúdo ao vivo transmitido online nas edições do TDC, agora você pode ter acesso à centenas de palestras gravadas, através da nossa nova plataforma de vídeos - o TDC Online, que reúne todas as Trilhas premium, Stadium e Salas dos Patrocinadores das edições anteriores de 2022, TDC Innovation e TDC Connections.  Para acessar, basta clicar na edição em que você participou ( TDC Innovation ou TDC Connections ); Fazer o mesmo login (com e-mail e senha) cadastrados na hora de adquirir ou resgatar o seu ingresso no TDC; E clicar na Trilha de sua opção, e de acordo com a modalidade do seu ingresso. Logo em seguida, você será direcionado para a seguinte página com a lista de todas as palestras por Trilha: Pronto! Agora você tem acesso à centenas de palestras gravadas da sua área de interesse, para assistir como e quando quiser! Caso tenha esquecido a senha, clique na opção "Esqueci a senha" , insira o e-mail que você realizou para o cadastro no evento, e aparecerá a op...

O que é Lógica de programação?

Este é o segundo de uma série de posts voltados aos leitores do blog que estão dando início à carreira de desenvolvimento de software. O assunto de hoje é a lógica de programação. Para ler antes: Entendendo como funciona a programação de computadores: linguagens de programação, lógica, banco de dados A lógica de programação é um pré-requisito para quem quer se tornar um desenvolvedor de software, independente da linguagem de programação que se pretende utilizar. Mas o que é de fato a Lógica de Programação e como saber se eu tenho esse pré-requisito? A lógica de programação nada mais é do que a organização coerente das instruções do programa para que seu objetivo seja alcançado. Para criar essa organização, instruções simples do programa, como mudar o valor de uma variável ou desenhar uma imagem na tela do computador, são interconectadas a estruturas lógicas que guiam o fluxo da execução do programa. Isso é muito próximo ao que usamos em nosso cotidiano para realizar atividad...

EJB 3: Uma evolução sob os conceitos do Hibernate e Spring

Definitivamente o modelo de componentização definido no Java EE 5 e 6 evoluiu e melhorou muito. Mas, sem dúvida muita dessa evolução se deve às pressões do Hibernate e Spring Framework. Estes dois últimos frameworks nasceram baseados no conceito de POJO, que nada mais é do que a concepção de um modelo de componentização baseado em classes Java sem as regras impostas pelo EJB (curioso, sem o EJB não existiria o Hibernate ou o Spring). A morte dos Entity Beans O Hibernate nasceu da idéia de promover um modelo de persistência mais simples que o proposto pelos EJBs do tipo Entity Beans definido na especificação EJB 2.x. Este foi o primeiro tipo de EJB a sofrer com a evasão de desenvolvedores com o surgimento deste framework e a conscientização sobre os problemas nos Entity Beans. A partir de um modelo baseado em JavaBeans e o uso do JDBC, o Hibernate usa a Reflection API para gerar os SQLs necessários para persistir o estado de beans em diversos banco de dados relacionais, além de defini...

TDC BUSINESS, chega a São Paulo com novas trilhas de Inteligência Artificial e Inovação

Maior conferência de profissionais de tecnologia do Brasil abordará temas em alta no momento como, por exemplo, Inteligência Artificial, Segurança, Ciência de Dados e Inovação O TDC BUSINESS, a 17° edição do The Developer's Conference na cidade de São Paulo, que acontece entre os dias 19 e 21 de Setembro, reunirá profissionais e especialistas da área para troca de experiência, compartilhamento de conteúdos e networking. Com o tema central: “Tecnologia para negócios transformadores”, o evento será totalmente híbrido, ocorrendo presencialmente no espaço Pro Magno, e com transmissão simultânea e atividades de network pela internet. A expectativa é reunir mais de 14.000 pessoas, somando a participação presencial e online.   Segundo Yara Mascarenhas, Fundadora e Host do Evento, “nosso objetivo com o TDC é inspirar a colaboração entre os profissionais e empresas para construir uma nova realidade para o mercado de TI.  Vamos juntar tecnologia e negócios com as trilhas técnicas...