Enviar arquivo por Socket

2 respostas
long

Gostaria que vocês me dessem uma luz em relação a Socket..
Seguinte, estou tentando enviar um arquivo de um Cliente para um de dois ServidoresEscravos mas para isso tem um ServidorCentral no meio que por exemplo, verifica para qual escravo ele repassa o arquivo e o escravo salva (no caso, verifico quantos arquivos tem a pasta e faco um mod2)
ex: Cliente -> Servidor -> Escravo1/Escravo2
Enviar o arquivo do cliente para o servidor ate que estou conseguindo o problema chega quando eu tento enviar do servidor para o escravo

No Servidor:

public void run() {
        
        try {
            diretorio = "E:\\Teste Socket";
            File dir = new File(diretorio);
            File fList[] = dir.listFiles();
            int total = fList.length;
            File file = (File) input.readObject();
            System.out.println("Arquivo" + file);
            
            Escravos(total,file);
        
            socket.close();    
        } catch (IOException ex) {
            Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public Socket Escravos(int valor, File file){
            Socket escravo = null; 
            System.out.println("Numero par");
            try {
                if(valor %2 == 0){
                escravo = new Socket("localhost", 1235);
                                
                System.out.println("Enviado para o escravo 1");
            }
            else {
                System.out.println("Numero impar");
                escravo = new Socket("localhost", 1236);

                System.out.println("Enviado para o escravo 2");                
            }
            ObjectOutputStream saida = new ObjectOutputStream(escravo.getOutputStream());
            saida.writeObject(file);
            escravo.close();
            } catch (UnknownHostException ex) {
                Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
            }

        return escravo;
    }

No escravo:

public class Escravo1 {
    private ServerSocket server;
    private Socket socket;
    private ObjectInputStream input;
    
    public static void main(String[] args) throws IOException{
        Escravo1 slave = new Escravo1();
        slave.server = new ServerSocket(1235);
        slave.socket = slave.server.accept();
        slave.input = new ObjectInputStream(slave.socket.getInputStream());
        try {
            File file = (File) slave.input.readObject();
            File novoFile = new File("E:\\Teste Socket\\"+file.getName());
            Path path = novoFile.toPath();
            Files.copy(new FileInputStream(file), path, StandardCopyOption.REPLACE_EXISTING);
            System.out.println("Nome do arquivo" +file.getName());
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Escravo1.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Dá erro quando eu tento instanciar um novo socket no metodo escravos. Alguem saberia o por que e teria alguma sugestão?

2 Respostas

gomesrod

Olá,

Antes de mais nada, tem uma confusão muito séria aí: você não está enviando o conteúdo do arquivo entre as pontas, está enviando apenas o objeto File que nada mais é do que um objeto que contém as informações do arquivo (nome, tipo, existe ou não existe, etc).

Ao receber você manda abrir o arquivo e então copia seu conteúdo. Perceba que isso só está funcionando por acaso, porque estão todos na mesma máquina!

Em outras palavras, em vez de fazer isso:

code Cliente lê o arquivo no computador 1 -> (2) Cliente envia o conteúdo do arquivo (bytes)
-> (3) Serviço recebe os bytes -> (4) Serviço grava esses bytes em um novo arquivo, no computador 2[/code]
Você está fazendo isso:

code Cliente envia o nome do arquivo -> (2) Serviço recebe o nome do arquivo
-> (3) Servidor manda copiar esse arquivo para um novo. Esse passo só funciona se estiver na mesma máquina do arquivo original [/code]
Aqui eu eliminei a parte da seleção de escravos, só pra simplificar, mas a idéia é essa.

É realmente o que você quer (mandar apenas o nome do arquivo) ? Ou foi apenas um engano? Se não foi a intenção por favor reveja o código, procure estudar o funcionamento das APIs utilizadas (File, ObjectInputStream, ObjectOutputStream), no processo você pode acabar corrigindo o erro sem perceber

Se o que quer é rodar tudo em uma mesma máquina talvez nem precise do socket.

[EDITADO]
Outra coisa que precisa prestar atenção, esqueci de dizer: Se a informação está sendo gerada no próprio Servidor na hora de mandar para o Escravo onde é que entra o cliente?

long

gomes

primeiramente vlw por ter respondido o post e me tirou certas duvidas que possuia.. de fato msm só funciona na msm maquina o Copy.. tentei revisa o codigo e tentei fazer de uma outra maneira. Acredito que agora estou enviar os bytes do cliente para o servidor mas ficou em outra situacao:

Cliente:
public Carregar(String diretorio) throws IOException{
        this.diretorio = diretorio;
        System.out.println(this.diretorio);
        socket = new Socket("localhost", 1234);
        //input = new ObjectInputStream(socket.getInputStream());
        output = new ObjectOutputStream(socket.getOutputStream());
        File file = new File(this.diretorio);
        FileInputStream arquivo = new FileInputStream(file);
        int tamanho = (int)file.length();
        output.writeInt(tamanho);
        output.writeUTF(file.getName());
        byte[] buffer = new byte[tamanho];
        while(true){
            int len = arquivo.read(buffer);
            if(len == -1) break;
            output.write(buffer, 0, len);
            System.out.println(tamanho);
            System.out.println("Arquivo enviado");
        }
        
    }

Servidor:

public void run(){
        try {
            int tamanho = input.readInt();
            String nomeArq = input.readUTF();
            FileOutputStream file = new FileOutputStream("E:\\Teste Socket\\"+nomeArq);
            byte[] buffer = new byte[tamanho];
            while(true){
                int len = input.read(buffer);
                if(len == -1) break;
                file.write(buffer, 0, len);
            }
            System.out.println("Arquvio Recebido");
        } catch (IOException ex) {
            Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Ele chega ate enviar os bytes blz so que o problema esta nesse meu laco.. pelo que percebi ele recebe os dados mas n faco o file.write pq ele n chega a receber -1.. Para eu poder visulizar o arquivo eu preciso parar de rodar o servidor para poder abrir

Criado 20 de março de 2013
Ultima resposta 21 de mar. de 2013
Respostas 2
Participantes 2