Olá a todos.
Sou, de certa forma, iniciante em java, e estou com uma dúvida num programa que fiz. Eu sei que existem tópicos específicos sobre programas cliente/servidor usando sockets como o meu, mas resolvi criar esse tópico aqui pois acredito que o problema no meu programa não é na troca de informações em si. O problema é o seguinte: o objetivo do programa é que exista um servidor capaz de fornecer a um cliente um arquivo ou dados sobre esse arquivo quantas vezes o cliente desejar. Para isso no programa cliente existe um menu onde o usuário escolhe que função vai usar e cada função envia um inteiro ao servidor dizendo a ele o que fazer. A função de enviar dados do arquivo ao cliente funciona perfeitamente, quantas vezes o cliente desejar. O porém é que a função de envio de arquivos funciona uma única vez. Após enviar o arquivo para o cliente, está ocorrendo algum erro e o programa encerra. Detalhe que o arquivo chega perfeitamente no cliente, o servidor só não consegue pegar o proximo inteiro correspondente a qual funcão ele deve executar em seguida. Segue os códigos:
Servidor:
package teste_servidor3;
import java.io.;
import java.net.;
import javax.swing.;
import java.util.;
import java.text.*;
public class Main {
static final int porta = 5050; //Define a porta a ser usada para a conexão.
static final int bloco = 1024 * 4; //Define o tamanho do bloco de bytes a ser enviado por vez, na trasferência.
public static void main(String[] args) {
try {
System.out.println("Abrindo Socket...");
ServerSocket server = new ServerSocket(porta); //Cria um socket tipo servidor na porta especificada.
System.out.println("Socket Aberto");
JOptionPane.showMessageDialog(null, "Servidor Online.\n Aguardando conexão.");
System.out.println("Aguardando Conexão...");
int flag = 1; //Variável de controle que mantem o servidor executando.
while(flag == 1){ //Permanece no loop até que flag seja modificado na função 'encerra'.
Socket client = server.accept(); //Espera até que um cliente se conecte ao servidor.
System.out.println("Conexão estabelecida com sucesso");
int option;
DataInputStream fromClient = new DataInputStream(client.getInputStream());
DataOutputStream toClient = new DataOutputStream(client.getOutputStream());
do{
option = fromClient.readInt(); //Recebe do cliente a função que deve ser executada.
System.out.println(option);
switch(option){
case 1: envia_arquivo(fromClient,toClient); //Função responsável por enviar o arquivo ao cliente.
break;
case 2: envia_dados(fromClient, toClient); //Função responsável por enviar dados do arquivo ao cliente.
break;
case 3: flag = encerra(client,server,fromClient,toClient); //Função responsável por encerrar o servidor.
break;
default: System.out.println("O servidor nao pode executar a requisicao.");
}
}while(option != 3); //Permanece no loop até que o cliente insira a opção 3.
}
}catch (Exception e) {
System.err.println("ERRO: "+e.getMessage());
}
}
static void envia_arquivo(DataInputStream fromClient, DataOutputStream toClient){
try{
String nome = fromClient.readUTF(); //Recebe do cliente o nome do arquivo que deve ser enviado.
System.out.println(nome);
//String diretorio = JOptionPane.showInputDialog(null, “Insira o diretório onde se encontra o arquivo no servidor.”);
File arquivo = new File(“C:\” + nome);
DataInputStream in = new DataInputStream(new FileInputStream(arquivo));
long aux = arquivo.length(); //Pega o tamanho do arquivo.
String aux2 = String.valueOf(aux);
toClient.writeUTF(aux2); //Envia o tamanho do arquivo para o cliente.
System.out.println(aux2);
int tamanho = Integer.parseInt(aux2);
System.out.println("Enviando arquivo...");
int pacote = bloco;
int count = tamanho;
byte[] buffer = new byte[pacote]; //Cria um buffer que armazenará blocos de bytes do arquivo a serem enviados.
while (count > -1){ //Permanece enviando ao cliente até que 'count' seja 0.
int caracter = in.read(buffer, 0, pacote);
toClient.write(buffer, 0, caracter);
count = count - caracter;
if(count == 0) break;
}
toClient.flush();
in.close();
System.out.println("Arquivo enviado com sucesso.");
}catch (Exception e) {
System.err.println("ERRO: "+e.getMessage());
}
}
static void envia_dados(DataInputStream fromClient, DataOutputStream toClient){
try{
String nome = fromClient.readUTF(); //Recebe do cliente o nome do arquivo sobre o qual ele deseja informações.
//String diretorio = JOptionPane.showInputDialog(null, “Insira o diretório onde se encontra o arquivo no servidor.”);
File arquivo = new File(“C:\” + nome);
long lastModified = arquivo.lastModified(); //Pega a data na qual o arquivo foi modificado pela ultima vez.
DateFormat formato = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); //Coloca a hora no formato especificado.
String data = formato.format (new Date(lastModified));
toClient.writeUTF(data); //Envia a data para o cliente.
}catch (Exception e) {
System.err.println("ERRO: "+e.getMessage());
}
}
static int encerra(Socket client,ServerSocket server, DataInputStream fromClient,DataOutputStream toClient){
int flag = 1;
try{
toClient.close(); //Fecha a stream de saida.
fromClient.close(); //Fecha a stream de entrada.
client.close(); //Fecha o socket do cliente.
int confirmacao= JOptionPane.showConfirmDialog(null, “Deseja fechar o servidor?”); //Confirma o encerramento do servidor.
if(confirmacao == JOptionPane.YES_OPTION) {
System.out.println("Servidor encerrado.");
server.close(); //Se sim, fecha o socket servidor e torna flag igual a '0'.
flag = 0;
}
else{
flag = 1; //Se não, mantem flag igual a '1', o que permitira que outro cliente se conecte ao servidor.
System.out.println("Aguardando conexão...");
}
}
catch(Exception e){
System.err.println("ERRO: "+e.getMessage());
}
return flag;
}
}
Cliente:
package teste_cliente3;
import java.io.;
import java.net.;
import javax.swing.*;
public class Main {
static final int porta = 5050; //Define a porta a ser usada para a conexão.
static final int bloco = 1024 * 4; //Define o tamanho do bloco de bytes a ser enviado por vez, na trasferência.
public static void main(String[] args) {
int resposta = JOptionPane.showConfirmDialog(null, "Deseja se conectar ao servidor?" );
if(resposta == JOptionPane.YES_OPTION){ //Oferece ao cliente a opção de se conectar ao servidor.
Socket clientSocket = connect(); //Chama a função responsável por estabelecer a conexão.
try {
System.out.println("Conexão estabelecida com sucesso.");
DataOutputStream toServer = new DataOutputStream(clientSocket.getOutputStream());
DataInputStream fromServer = new DataInputStream(clientSocket.getInputStream());
menu(toServer, fromServer, clientSocket); //Chama a função que oferece as opções disponíveis ao cliente.
toServer.close(); //Fecha a stream de saída.
fromServer.close(); //Fecha a stream de entrada.
clientSocket.close(); //Fecha o socket cliente.
}catch(Exception e){
System.err.println("Erro: " + e.getMessage());
}
}
else{
JOptionPane.showMessageDialog(null, "Fim da execução.");
System.exit(0);
}
}
static Socket connect(){
Socket clientSocket = null; //Declara o socket cliente.
try {
System.out.println(“Abrindo Socket…”);
String ip = JOptionPane.showInputDialog(null, “Insira o IP do servidor.”); //Pega o IP do servidor.
clientSocket = new Socket(ip, porta); //Se conecta ao servidor na porta pré definida.
}
catch(Exception e){
System.err.println("Erro: " + e.getMessage());
}
return clientSocket;
}
static void menu(DataOutputStream toServer, DataInputStream fromServer, Socket clientSocket){
int opcao;
try{
do {
opcao = Integer.parseInt(javax.swing.JOptionPane.showInputDialog(“Escolha uma das opções abaixo:\n” +
“1 - Transferência de arquivo.\n” +
“2 - Data de modificação do arquivo.\n” +
“3 - Encerrar a conexão e sair.\n”));
switch (opcao){
case 1: transferencia(toServer, fromServer, clientSocket); //Função responsável por receber o arquivo do servidor.
break;
case 2: dado_arquivo(toServer, fromServer); //Função responsável por receber dados sobre o arquivo.
break;
case 3: toServer.writeInt(3); //Manda para o servidor o identificador de que o cliente deseja encerrar a conexão.
JOptionPane.showMessageDialog(null, “Conexão encerrada.”);
break;
default: JOptionPane.showMessageDialog(null, “A opção digitada é invalida.\n Escolha uma opção válida para continuar.”);
}
}while(opcao != 3); //Continua no loop até que o cliente insira a opção ‘3’.
}catch(Exception e){
System.err.println("Erro: " + e.getMessage());
}
}
static void transferencia(DataOutputStream toServer, DataInputStream fromServer, Socket clientSocket){
try{
toServer.writeInt(1); //Manda para o servidor o identificador de que o cliente deseja transferir um arquivo.
String nome = JOptionPane.showInputDialog(null, "Insira o nome do arquivo que deseja baixar.");
toServer.writeUTF(nome); //Manda para o servidor o nome do arquivo a ser baixado.
System.out.println(nome);
//String diretorio = JOptionPane.showInputDialog(null, "Insira o diretorio onde deseja salvar o arquivo.");
DataOutputStream out = new DataOutputStream (new FileOutputStream("D:\\" + nome));
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
String size = fromServer.readUTF(); //Recebe do servidor o tamanho do arquivo.
System.out.println(size);
int tamanho = Integer.parseInt(size);
int pacote = bloco;
int count = tamanho;
byte[] buffer = new byte[pacote]; //Cria um buffer para receber o arquivo.
System.out.println("Recebendo arquivo...");
while(count > -1) { //Permanece no loop até que contador se torne '0'.
int readByte = in.read(buffer, 0, pacote);
out.write(buffer, 0, readByte); //Escreve os blocos de bytes recebidos no arquivo criado.
count = count - readByte;
if (count == 0) break;
}
System.out.println("Arquivo recebido com sucesso.");
out.flush();
out.close(); //Fecha a stream de saida.
in.close(); //Fecha a stream de entrada.
JOptionPane.showMessageDialog(null, "Arquivo recebido com sucesso.");
}catch(Exception e){
System.err.println("Erro: " + e.getMessage());
}
}
static void dado_arquivo(DataOutputStream toServer, DataInputStream fromServer){
try{
toServer.writeInt(2); //Manda para o servidor o identificador de que o cliente deseja dados arquivo.
String nome = JOptionPane.showInputDialog(null, "Insira o nome do arquivo.");
toServer.writeUTF(nome); //Manda para o servidor o nome do arquivo.
String data = fromServer.readUTF(); //Recebe do servidor, a data de modificação do arquivo.
JOptionPane.showMessageDialog(null, "A data de modificação do arquivo é: \n" + data );
}catch(Exception e){
System.err.println("Erro: " + e.getMessage());
}
}
}