Conexao Socket internet (Pane Cabeluda)

Bom dia todos, estou com uma pane cabeluda:

Crieie uma estrutra cliente servidora que utiliza socket para se comunicar, até ai tudo bem. Quando utilizo a estrutura dentro de uma LAN ela funciona perfeitamente.
O problema começa quando eu tento utiliza-la na internet, através de um IP válido.
Por cerca de uns 5 minutos o sistema troca dados entre o cliente e o servidor normalmente, como se estivesse em uma LAN, porém mais ou menos ao fim desse prazo os sockets param de se comunicar como se um não “visse” o outro.
Detalhes:
1 - O cliente interroga o servidor de 1 em 1 minuto no mesmo ip e na mesma porta; (Se é FireWall então porque não barra desde o início ?);
2 - O servidor é o 2003 server, acredito ser o vilão da história, o IIS não foi levantado;
3 - O Firewall está totalmente desabilitado;
4 - Após uma espera de cerca de 30 minutos, o sistema consegue novamente reestabelecer a conexão por cerca de mais uns 5 minutos.

Alguém saberia me indicar o que poderia estar causando isto, e, se possível, uma solução ?

Será que vc pode postar a parte do código do cliente e do servidor onde estabelecem a conexão?

O código Cliente é este:

void solicitarDados(){
        try{
            boolean agd = false;
            int intervaloSolicitacao = 10000;
            int quantidadeLoops = 0;
            File dir = new File("./transferencia/");
            if (!dir.exists()){
                dir.mkdir();
            }
            
            //Este trecho só é necessário quando se optar por uma conexão discada, para as demais ele é inerte
            FormDiscador form = null;
            if (super.getDiscador() != null && super.getDiscador().getForm() != null){
                form = super.getDiscador().getForm();
            }
                
            MatrizFilial estaFilial = MatrizFilialBD.getFilial(propriedades.getPropriedade(Props.FilialAjustada.getIdentificador()));
                    
            while(!encerrar){                
                
                boolean transmidos = false;
                try{
                    if (agd) try{Thread.sleep(intervaloSolicitacao = intervalo);}catch(Exception e){};
                    agd = true;
                    
                    
                    //System.out.println("Solicitando dados a matriz... " + getHostMestre());
                    String ipCliente = "";
                    boolean enviar = true;
                    quantidadeLoops++;
                    
                    if (form != null) form.setResumo("Tentando conexão de dados com a matriz...",form.ICONE_CONEXAO);
                    
                    Socket cliente = new Socket(super.getHostMestre(),PORTA); 
                    ipCliente = cliente.getInetAddress().getHostAddress();
                    
                    if (form != null) form.setResumo("Estabelecida conexão com a matriz...",form.ICONE_OK);
                    
                    DataInputStream dis = new DataInputStream(cliente.getInputStream());                    
                    DataOutputStream dos = new DataOutputStream(cliente.getOutputStream());
                    
                    File arquivoEnviar = getArquivoEnviar();
                    
                    String md5Enviada = arquivoEnviar != null ? Criptografa.getMD5(arquivoEnviar) : "NIL";
                    
                    dos.writeInt(estaFilial.getCodigo());
                    dos.writeUTF(md5Enviada);
                    //dos.flush(); 
                    
                    boolean confirmarRecebimento = false;
                    
                    if (md5Enviada.equals("NIL")){
                        if (form != null) {
                            form.setDadosEnviados("Não há dados a enviar...",form.ICONE_OK);
                            form.setAutenticacaoEnviados("Não requer autenticação...",form.ICONE_OK);
                        }
                        intervaloSolicitacao = getIntervalo_posconfirmado();
                    }else{
                        FileInputStream fis = null;                    
                        fis = new FileInputStream(arquivoEnviar);
                        int quantidadeBytes = fis.available();                        
                        byte[] dados = new byte[quantidadeBytes];
                        
                        dos.writeInt(quantidadeBytes);
                        
                        fis.read(dados);
                        dos.write(dados,0,dados.length);
                        dos.flush();
                        if (form != null) form.setDadosEnviados("Enviados " + dados.length + " bytes...",form.ICONE_OK);
                        //System.out.println("Transmitidos " + dados.length + " bytes...");
                        fis.close();
                        
                        
                        //CONFIRMA SE A AUTENTICAÇÃO OCORREU DE ACORDO
                        confirmarRecebimento = dis.readBoolean();
                        
                        if (confirmarRecebimento){
                            estoquebd.marcarComoEnviadas(0);
                            notabd.marcarComoEnviadas(0);
                            if (form != null) form.setAutenticacaoEnviados("Autenticados com sucesso...",form.ICONE_OK);
                            //System.out.println("Recebimento confirmado pela matriz, os dados foram marcados como enviados...");
                        }else{
                            if (form != null) form.setAutenticacaoEnviados("Falha de autenticação...",form.ICONE_FALHA);
                        }
                        
                    }
                                        
                    dos.close();
                    dis.close();
                    
                    cliente = new Socket(getHostMestre(),PORTA);
                    dis = new DataInputStream(cliente.getInputStream());                    
                    dos = new DataOutputStream(cliente.getOutputStream());
                    
                    
                    String md5Recebida = dis.readUTF();
                    
                    boolean confere = false;
                    
                    if (!md5Recebida.equals("NIL")){
                        ArrayList<Byte> bytes = new ArrayList<Byte>();
                        String arquivo = "transferencia/dados_recebidos" + super.getDDHHMMSS() + ".rcb";
                        FileOutputStream fos = new FileOutputStream(arquivo);
                    
                        int quantidadeBytes = dis.readInt();
                                
                        int cont = 0;
                        while(cont < quantidadeBytes){

                            int b = dis.read();                                    
                            fos.write(b);
                            cont++;
                        }

                        fos.flush();
                        fos.close();
                        
                        System.out.println("Recebidos " + quantidadeBytes + " bytes...");
                        if (form != null) form.setDadosRecebidos("Recebidos " + quantidadeBytes + " bytes...",form.ICONE_OK);
                        String md5ArquivoRecebido = Criptografa.getMD5(new File(arquivo));
                        confere = md5ArquivoRecebido.equals(md5Recebida);
                        
                        dos.writeBoolean(confere);
                        dos.flush();
                        //System.out.println("Recebimento confirmado pela filial, os dados foram marcados como enviados...");
                        
                        if (confere){
                            if (form != null) form.setAutenticacaoRecebidos("Autenticados com sucesso...",form.ICONE_OK);
                            synchronized(CambioDadosCliente.this){
                                CambioDadosCliente.this.notify();
                            }                                    
                        }else{
                            if (form != null) form.setAutenticacaoRecebidos("Falha de autenticação...",form.ICONE_FALHA);
                            File f = new File(arquivo);
                            f.delete();
                        }
                    }else{
                        if (form != null) {
                            form.setDadosRecebidos("Não há dados a receber...",form.ICONE_OK);
                            form.setAutenticacaoRecebidos("Não requer autenticação...",form.ICONE_OK);
                        }
                    }                                        
                        
                    transmidos = true;
                    
                    dis.close();                               
                    dos.close();
                    cliente.close();
                    
                    if (confere){                        
                        intervaloSolicitacao = getIntervalo_posconfirmado();
                    }
                    
                    if (form != null) {
                        form.setResumo("Operação realizada com sucesso...",form.ICONE_OK);
                    }
                    
                }catch(Exception ex){
                    
                }finally{    
                    
                    if (form != null && (super.getDiscador().getTentativasRespostaMatriz() < quantidadeLoops || transmidos)){
                        if (!transmidos) form.setResumo("Matriz não responde...",form.ICONE_FALHA);
                        notificar(transmidos);
                        break;
                    }
                    
                }
            }
            
        }catch(Exception e){
            e.printStackTrace();
        }
        
    }

Aqui está a parte do servidor:
void receberDados(){

    carregarArquivosRecebidos();
    
    Thread t = new Thread("Receber dados ... "){
        public void run(){                
            
            try{
                
                ServerSocket servidor = new ServerSocket(PORTA);
                File dir = new File("./transferencia/");
                if (!dir.exists()){
                    dir.mkdir();
                }
                
                while(!encerrar){
                    
                    boolean transmidos = false;
                    
                    //System.out.println("Aguardando conexão cliente...");
                    try{
                        servidor.setSoTimeout(0);
                        Socket cliente = servidor.accept();           
                        final String ipCliente = cliente.getInetAddress().getHostAddress();
                        DataOutputStream dos = new DataOutputStream(cliente.getOutputStream());
                        DataInputStream dis = new DataInputStream(cliente.getInputStream());
                        
                        System.out.println("IP CLIENTE: " + cliente.getInetAddress().getHostAddress());
                        int codigoFilialRecebida = dis.readInt();      
                        //System.out.println("Recebida a filial " + codigoFilialRecebida +  "...");
                        
                        String md5Recebido = dis.readUTF();
                        //System.out.println("Código md5 recebido " + md5Recebido +  "...");
                        
                        if (md5Recebido.equals("NIL")){
                            //System.out.println("Nenhum dado recebido do cliente...");
                        }else{
                            String nomearq = "transferencia/recebido" + getDDHHMMSS() + "_" + codigoFilialRecebida + ".rcb";
                            FileOutputStream fos = new FileOutputStream(new File(nomearq));                            
                            ArrayList<Byte> bytes = new ArrayList<Byte>();
                            
                            int quantidadeBytes = dis.readInt();
                            
                            int cont = 0;
                            while(cont < quantidadeBytes){
                                
                                int b = dis.read();
                                fos.write(b);
                                cont++;
                            }
                            
                            fos.flush();
                            fos.close();
                            
                            //System.out.println("Recebidos " + cont + " bytes...");
                            
                            String md5ArquivoRecebido = Criptografa.getMD5(new File(nomearq));
                            boolean conferido = md5ArquivoRecebido.equals(md5Recebido);
                            dos.writeBoolean(conferido);
                            
                            if (conferido){
                                synchronized(CambioDadosServidor.this){
                                    CambioDadosServidor.this.notify();
                                }                                    
                            }else{
                                File f = new File(nomearq);
                                f.delete();
                            }
                        }
                        
                                                   
                        dis.close();
                        dos.close();  
                        
                        try{
                            while(true){
                                servidor.setSoTimeout(10000);//aguarda até 10 segundos para receber uma resposta do cliente
                                                             //se os 10s expirarem uma exceção será lançada
                                cliente = servidor.accept();
                                String ipClienteReconexao = cliente.getInetAddress().getHostAddress();
                                if (ipClienteReconexao.equals(ipCliente)) break;
                            }
                        }catch(Exception e){                
                            cliente.close();
                            continue;
                        }
                        dos = new DataOutputStream(cliente.getOutputStream());
                        dis = new DataInputStream(cliente.getInputStream());
                        
                        File arquivoEnviar = getArquivoEnviar(codigoFilialRecebida);
                
                        String md5Enviada = arquivoEnviar != null ? Criptografa.getMD5(arquivoEnviar) : "NIL";
                        
                        dos.writeUTF(md5Enviada);
                        dos.flush();
                        
                        if (!md5Enviada.equals("NIL")){
                            
                            FileInputStream fis = null;                    
                            fis = new FileInputStream(arquivoEnviar);
                            int quantidadeBytes = fis.available();
                            byte[] dados = new byte[quantidadeBytes];
                            
                            dos.writeInt(quantidadeBytes);
                            
                            fis.read(dados);
                            dos.write(dados,0,dados.length);
                            //System.out.println("Transmitidos " + dados.length + " bytes para filial " + codigoFilialRecebida + "...");

                            //CONFIRMA SE A AUTENTICAÇÃO OCORREU DE ACORDO
                            boolean confirmarRecebimento = dis.readBoolean();

                            if (confirmarRecebimento){
                                marcarDadosComoEnviados(codigoFilialRecebida);
                                //System.out.println("Recebimento confirmado pela filial, os dados foram marcados como enviados...");
                            }

                        }else{
                            //System.out.println("Não há dados a serem enviados...");
                        }
                        
                        transmidos = true;
                        try{
                            //System.out.println("CambioDadosServidor.super.getDiscador() = " + CambioDadosServidor.super.getDiscador());
                            if (CambioDadosServidor.super.getDiscador() != null){
                                synchronized(CambioDadosServidor.super.getDiscador()){
                                    //System.out.println("Notificando discaor...");
                                    CambioDadosServidor.super.getDiscador().setBemSucedido(transmidos);
                                    CambioDadosServidor.super.getDiscador().notify();
                                }
                            }
                        }catch(Exception ec){}
                        dis.close();                            
                        dos.flush();                            
                        dos.close();
                        cliente.close();
                                                    
                    }catch(Exception e){
                        e.printStackTrace();
                    }finally{                
                        try{
                            if (CambioDadosServidor.super.getDiscador() != null){
                                synchronized(CambioDadosServidor.super.getDiscador()){
                                    //System.out.println("Notificando discaor...");
                                    CambioDadosServidor.super.getDiscador().setBemSucedido(transmidos);
                                    CambioDadosServidor.super.getDiscador().notify();
                                }
                            }
                        }catch(Exception ec){}
                    
                    }
                    
                }
                servidor.close();
            }catch(Exception e){
                //e.printStackTrace();                    
            }
            
        }
    };
    t.start();
}