Transferência de arquivos via Socket - Erro

Boa tarde!

Estou executando uma transferência de arquivos via socket. Inicialmente utilizei um mesmo IP local para o SERVIDOR e CLIENTE, como se os dois estivessem no mesmo computador e deu tudo certo, porém quando altero o IP para o servidor de verdade o sistema trava e da um erro. Alguém poderia me ajudar? Sou novo nessa área de programação.

Segue o erro:

-Fev 21, 2017 3:06:37 PM Teste.Janela_Cliente b_enviarActionPerformed
GRAVE: null
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.(Socket.java:425)
at java.net.Socket.(Socket.java:208)
at Teste.Janela_Cliente.b_enviarActionPerformed(Janela_Cliente.java:189)
at Teste.Janela_Cliente.access$200(Janela_Cliente.java:23)
at Teste.Janela_Cliente$3.actionPerformed(Janela_Cliente.java:84)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6516)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6281)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4872)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:747)
at java.awt.EventQueue.access$300(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:706)
at java.awt.EventQueue$3.run(EventQueue.java:704)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:720)
at java.awt.EventQueue$4.run(EventQueue.java:718)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:717)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

Você consegue dar ping no IP do servidor, da máquina do cliente?

Consegui sim.

Já viu se não tem nenhum firewall no servidor bloqueando a conexão?

Já conferia também. Desabilitei o Firewall do servidor, mas continuou gerando o mesmo erro.
Fiz o teste também em uma outra máquina qualquer, usando ela como servidor, mas deu o mesmo problema.
Procurei alguns códigos no Google e até no Youtube, mas no final todos geraram o mesmo erro.
Provavelmente o erro esteja no computador e não no código, mas não faço ideia do que possa ser.

Pode ser uma pergunta idiota, mas vale a pena conferir: Você tá usando as portas certas? A porta que o cliente tá tentando conectar é a mesma que o ServerSocket tá ouvindo?

Não é uma pergunta idiota. As vezes a gente da umas mancadas e faz isso mesmo, principalmente quando é novo nessa área de programação, o que é o meu caso. kkkkkkk
Mas eu conferi sim. Vou postar o meu código.

public class Cliente_2 {

public static void main(String[] args) {

    File f = new File("c:/a/teste.txt");
    try {

        Socket socket = new Socket("192.168.1.35", 9696); // IP servidor (máquina local)
       // Socket socket = new Socket("192.168.1.40", 9696); // IP servidor

        ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());

        System.out.println("Transferindo o arquivo: " + f.getName());
        out.writeUTF(f.getName());

        out.writeLong(f.length());
        FileInputStream in = new FileInputStream(f);
        byte[] buf = new byte[4096];

        while (true) {
            int len = in.read(buf);
            if (len == -1) {
                break;
            }
            out.write(buf, 0, len);
        }
        out.close();

        socket.close();
        System.out.println("Arquivo enviado com sucesso!.");
        
    } catch (IOException ex) {
        Logger.getLogger(Cliente_2.class.getName()).log(Level.SEVERE, null, ex);
    }
}

}

public class Servidor_2 {

public static void main(String[] args) {
    try {
        ServerSocket serv = new ServerSocket(9696); 

        while (true) {
            System.out.println("Aguardando Cliente...");

            Socket socket = serv.accept();
            
            ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
            
            String fileName = in.readUTF();
            
            long size = in.readLong();
            FileOutputStream fos = new FileOutputStream(fileName);
            byte[] buf = new byte[4096];
            while (true) {
                int len = in.read(buf);
                if (len == -1) {
                    break;
                }

                fos.write(buf, 0, len);
            }
            fos.flush();
            fos.close();
            System.out.println("Arquivo Recebido!");
        }

    } catch (IOException ex) {
        Logger.getLogger(Servidor_2.class.getName()).log(Level.SEVERE, null, ex);
    }
}

}

Outro lembrete: quando você executa o cliente, o servidor já deve estar em execução. Vou assumir que você já está fazendo isso! (Não custa lembrar hehe)

Experimenta fazer o seguinte:

  1. Executa o servidor em uma máquina

  2. Em outra máquina, a que seria a cliente, vai no terminal (de um sistema baseado em UNIX, tipo Linux ou MacOS) e abre uma sessão de telnet com o teu programa Java rodando no servidor, desse jeito:

     telnet 192.168.1.35 9696
    

O telnet, a grosso modo, vai tentar fazer exatamente o que teu programa cliente faz: abrir um socket tcp e conectar nesse IP e nessa porta. Depois, tudo o que vc digita no terminal é escrito pra OutputStream do servidor, e tudo o que o servidor escreve na tua OutputStream, aparece no teu terminal.

Se você estiver usando Windows, dá uma olhadinha no google como é que faz para utilizar telnet no cmd, não posso te ajudar com isso.

O intuito desse teste é verificar se é possível se conectar com o teu app no servidor quando ele está rodando. Se o telnet conectar, significa que o problema é no Client. Se não conectar, o problema é no servidor.

Consegui resolver!
O problema estava mesmo em meu computador.
O técnico aqui do escritório deu uma geral nele e o sistema funcionou perfeitamente.
Mas obrigado pela ajuda, lvbarbosa. :slight_smile: