Sockets com Java – Parte IV
Aprenda a desenvolver aplicações em Java que comunicam-se via rede local ou internet...
Aprenda a desenvolver aplicações em Java que comunicam-se via rede local ou internet
Um servidor TCP com múltiplos threads
Como vimos no nosso primeiro exemplo de servidor TCP, um servidor de produção não deve se limitar a processar uma conexão de cada vez, devendo ser capaz de atender inúmeras conexões simultaneamente. Veremos agora como montar um servidor TCP mais profissional usando threads.
Um caso prático do uso de sockets em Java
Vamos ver agora o exemplo de um cliente que solicita arquivos de imagem ao servidor. O cliente deve informar o caminho do arquivo no servidor, ao receber o pedido o servidor enviará o arquivo ao cliente. A aplicação exemplo solicita um arquivo JPG presente em um diretório do servidor, e ao receber o arquivo, exibe um JLabel o conteúdo do arquivo.
Para cada solicitação de cliente será criada uma nova thread para gerenciar a troca de mensagens, deixando assim o servidor livre para esperar por novas conexões. Vejamos detalhadamente este processo.
Na Listagem 5 temos o código do servidor de arquivos e na Listagem 6 o código da thread que trata do pedido específico. Na Figura 7 temos a aplicação em ação solicitando arquivos ao servidor e na Figura 8 temos o console de atividades do servidor. Na Listagem 7 você pode ver o código do botão Buscar da aplicação exemplo.
Listagem 5. Servidor de arquivos multithreaded
public class ServidorArquivo {
public static void main(String[] args) {
if(args.length < 1) {
System.out.println("Informe a porta a ser ouvida pelos servidor");
System.exit(0);
}
try {
//Converte o parametro recebido para int (número da porta)
int port = Integer.parseInt(args[0]);
System.out.println("Incializando o servidor...");
//Iniciliza o servidor
ServerSocket serv = new ServerSocket(port);
System.out.println("Servidor iniciado, ouvindo a porta " + port);
//Aguarda conexões
while(true) {
Socket clie = serv.accept();
//Inicia thread do cliente
new ThreadCliente(clie).start();
}
}
catch(Exception e) {...}
}
}
Listagem 6. Thread para tratar conexões recebidas pelo servidor
class ThreadCliente extends Thread {
private Socket cliente;
public ThreadCliente(Socket cliente) {
this.cliente = cliente;
}
public void run() {
try {
//ObjectInputStream para receber o nome do arquivo
ObjectInputStream entrada = new ObjectInputStream(cliente.getInputStream());
DataOutputStream saida = new DataOutputStream(cliente.getOutputStream());
//Recebe o nome do arquivo
String arquivo = (String)entrada.readObject();
//Buffer de leitura dos bytes do arquivo
byte buffer[] = new byte[512];
//Leitura do arquivo solicitado
FileInputStream file = new FileInputStream(arquivo);
//DataInputStream para processar o arquivo solicitado
DataInputStream arq = new DataInputStream(file);
saida.flush();
int leitura = arq.read(buffer);
//Lendo os bytes do arquivo e enviando para o socket
while(leitura != - 1) {
if(leitura != - 2) {
saida.write(buffer,0,leitura);
}
leitura = arq.read(buffer);
}
System.out.println("Cliente atendido com sucesso: " + arquivo +
cliente.getRemoteSocketAddress().toString());
entrada.close();
saida.close();
cliente.close();
}
catch(Exception e) {
System.out.println("Excecao ocorrida na thread: " + e.getMessage());
try {
cliente.close();
}
catch(Exception ec) {}
}
}
}
Listagem 7. Código do botão buscar arquivo presente na aplicação exemplo (Figura 6)
private void btnBuscarActionPerformed(java.awt.event.ActionEvent evt) {
try {
//Cria o Socket para buscar o arquivo no servidor
Socket rec = new Socket(txtServidor.getText(),Integer.parseInt(txtPorta.getText()));
//Enviando o nome do arquivo a ser baixado do servidor
ObjectOutputStream saida = new ObjectOutputStream(rec.getOutputStream());
saida.writeObject(txtArquivo.getText());
// DataInputStream para processar os bytes recebidos
DataInputStream entrada = new DataInputStream(rec.getInputStream());
//FileOuputStream para salvar o arquivo recebido
FileOutputStream sarq = new FileOutputStream(txtSaida.getText());
byte[] br = new byte[512];
int leitura = entrada.read(br);
while(leitura != -1) {
if(leitura != -2) {
sarq.write(br,0,leitura);
}
leitura = entrada.read(br);
}
saida.close();
entrada.close();
sarq.close();
rec.close();
ImageIcon img = new ImageIcon(txtSaida.getText());
lblImagem.setText("");
lblImagem.setIcon(img);
}
catch(Exception e) {
JOptionPane.showMessageDialog(null,"Exceção:" + e.getMessage(),"Erro",2);
}
}
Figura 7. Aplicação de exemplo que busca um arquivo JPG no servidor
Figura 8. Mensagens exibidas pela thread do servidor
Paulo Sérgio Pereira
Paulo Sergio Pereira (psergio.p@terra.com.br) Bacharel em Ciência da Computação pela Univap (Universidade do Vale do Paraíba) é desenvolvedor Java, Progress, Visual Basic, Visual C++.NET e ADVPL. É administrador de bancos de dados Progress, SQL Server 2000/2005 e DB2. Atua como desenvolvedor pela em...
1 COMENTÁRIO
//Inicia thread do cliente
new ThreadCliente(clie).start();
}
}
catch(Exception e) {...}
}
}
Aparece o seguinte erro illegal start of expression e aí eu não consigo compilar o programa, o que posso fazer para resolver, obrigado.



