Sockets

Galera estou utilizando Sockets na minha aplicação e ao transferir um objeto de um cliente para o servidor eu não obtenho mais resposta do mesmo e dpois de uns 20 segundos após enviado o objeto o servidor retorna um java.net.ConnectException: Connection timed out.
meu cliente esta escrito assim.

 Socket s = null;
        Socket aux = null;
        PrintStream ps = null;
         s = new Socket(ae.getIpServidor(), 7000);
         OutputStream out = s.getOutputStream();
         ObjectOutputStream os = new ObjectOutputStream(out);
            os.writeObject(ae);// escreve o objeto a ser enviado
            System.out.println("arquivo enviado ao servidor");
            ServerSocket ss = new ServerSocket(7003);
            aux = ss.accept();
            ObjectInputStream is = new ObjectInputStream(aux.getInputStream());
            RetornoServidorCliente retornoCliente = (RetornoServidorCliente) is.readObject();//objeto que o servidor deve retornar para o cliente
            System.out.println("a resposta do servidor foi "+retornoCliente.isRetorno());
            ss.close();
            aux.close();
            s.close();
            return retornoCliente.isRetorno();

agora meu código do servidor

ServerSocket serv = null;
        Socket s = null;
        Socket aux = null;
        serv = new ServerSocket(7000);
        Excel e = new Excel();
             System.out.println("aguardando arquivo do cliente");
            s = serv.accept();
            ponteServidorCliente = s;
            ObjectInputStream is = new ObjectInputStream(s.getInputStream());
            ArquivoEnvio chave = (ArquivoEnvio) is.readObject();
            System.out.println("arquivo recebido");
            if(chave==null){
                System.out.println("arquivo nulo");
                return;
            }
            e.exportarArquivo(chave,"Fortaleza");//aqui ele irá gerar um arquivo xls com o objeto passado pelo cliente
            System.out.println("arquivo gerado em c:/");
        
            aux = new Socket(chave.getIpCliente(), 7003);
            ponteClienteServidor = aux;
            OutputStream out = aux.getOutputStream();
                ObjectOutputStream os = new ObjectOutputStream(out);
                RetornoServidorCliente retornoCliente=null;
                if(chave.getLista().isEmpty())
                retornoCliente = new RetornoServidorCliente(false);
                else
                retornoCliente = new RetornoServidorCliente(true);
                os.writeObject(retornoCliente);
            System.out.println("resposta para cliente enviada");
            serv.close();
            s.close();
            aux.close();

iai alguem pode me ajudar?

Quer uma dica sutil?

Um colega meu foi demitido por teimar em usar um ObjectInput/OutputStream com sockets sem saber exatamente o que estava fazendo. Ele teimou tanto que estava certo (e não estava) que o pessoal se fartou dele e foi demitido, porque não conseguiu resolver o problema. Se você não souber o que está fazendo, você vai ter os seguintes problemas:

a) ObjectInput/OutputStream não é adequado para uso interativo (ou seja, um programa conversando com outro, através de envio e recepção de mensagens), porque os objetos são acumulados, não são imediatamente transmitidos/recebidos, mesmo com flush e outras técnicas que você possa tentar usar.
b) Se você não souber usar adequadamente o método “reset” (veja a documentação dele em http://java.sun.com/javase/6/docs/api/java/io/ObjectOutputStream.html ) você também vai ter um problema que é igualzinho ao famoso “memory leak” que tanto assola programas em C/C++.

Dica: Se ainda insistir em usar isso, em vez de encapsular diretamente o Socket em um ObjectInput/OutputStream, encapsule o socket em um DataInput/OutputStream, e serialize seus objetos para um array de bytes (usando ByteArrayInput/OutputStream + ObjectInput/OutputStream). Então crie um formato de mensagens mais ou menos assim:

2 bytes - comprimento da mensagem (use um readShort/writeShort de DataInput/OutputStream para ler/gravar esse valor
o array de bytes - contendo os seus dados.

Galera problema resolvido!
Meu firewall estava ligado enquanto o do outro pc não estava.
Por isso que havia a perda d pacotes na resposta do servidor.

Obrigado entanglement!
Ainda sou novo no mundo Socket.
Ainda estou estudando como funciona!
Você por gentileza poderia me explicar como funciona e para que usar o “reset”?

Obrigado!

Vou explicar como é que funciona um ObjectInput/OutputStream, para você entender por que é que é preciso o “reset”. (O que ele faz você pode ler na documentação que lhe passei).

Um ObjectOutputStream contém um hashmap contendo como chave um identificador sequencial de objetos, e como valor o objeto que você escreveu nele. Se esse objeto, por sua vez, for composto de outros objetos, então os outros objetos também são inseridos nesse hashmap.

No outro lado, o ObjectInputStream contém um hashmap parecido, que é usado para ajudar a remontar os objetos.

O problema é o seguinte: quando você usa um ObjectOutputStream para salvar dados em um arquivo (por exemplo), esse hashmap é útil porque ajuda a economizar espaço. Se um objeto já foi serializado, você não precisa serializar novamente o objeto - basta só gravar o identificador, para ajudar a recuperar o objeto. Mas quando você usa para enviar dados via sockets (que é um processo que pode ser considerado “infinito”), normalmente os objetos não dependem uns dos outros (99% do tempo você manda só parâmetros para algum método, como DAOs, ou comandos), então você não precisaria, a princípio, de ter esse tal hashmap. Só que esse hashmap não pode ser desligado, porque ele faz parte do funcionamento normal do ObjectInput/OutputStream.

O método “reset” limpa esse Hashmap dos dois lados (ObjectInput/OutputStream), então deve ser usado se você quer usar isso em sockets e não quer se preocupar se algum objeto é subobjeto de outro objeto.

Ok, não tão bem detalhado eu imaginei que isto poderia acontecer.
Por justa causa eu utilizo variaveis locais e sempre dou o close localizado dentro de um finnaly.
Com isso sei que ao sair do metodo os objetos respectivos ao objetcOutput/inputStream ficariam ao aguardo do garbageCollection tendo em vista que estes não teriam mais variaveis de referencia os apontando, já que haverá uma nova chamada ao método.

OU SEJA, COM UM PONTO DE VISTA DIFERENTE ACABEI POR CRIAR MEU PRÓRPIO RESET, SÓ QUE AO INVÉS DE LIMPAR OS HASHS EU DEIXO QUE O GARBAGE LIMPE OS OBJETOS NA MEMÓRIA.

[quote=igor_jua]Ok, não tão bem detalhado eu imaginei que isto poderia acontecer.
Por justa causa eu utilizo variaveis locais e sempre dou o close localizado dentro de um finnaly.
Com isso sei que ao sair do metodo os objetos respectivos ao objetcOutput/inputStream ficariam ao aguardo do garbageCollection tendo em vista que estes não teriam mais variaveis de referencia os apontando, já que haverá uma nova chamada ao método.

OU SEJA, COM UM PONTO DE VISTA DIFERENTE ACABEI POR CRIAR MEU PRÓRPIO RESET, SÓ QUE AO INVÉS DE LIMPAR OS HASHS EU DEIXO QUE O GARBAGE LIMPE OS OBJETOS NA MEMÓRIA.[/quote]

Não resolve. Você precisa do reset de vez em quando.