Re:Socket [Resolvido]

3 respostas
S
Boa tarde, Tenho uma aplicação que se comunica com outra via socket, porta 50010 para as requisições e respostas. Minha aplicação é o cliente, ou seja, o outro aplicativo é quem recebe a conexão. Meu problema é o seguinte, quando mando dados da o outro aplicativo ele recebe normal e faz o que tem que fazer, mas, eu só recebo a resposta de sucesso da operação se eu fechar o aplicativo servidor. Tentei criar uma thread em loop infinito para tentar receber a resposta mas sem sucesso. Tambem tentei fechar a conexão após o envio e abrir novamente para pegar a resposta, mas, tambem sem sucesso. Alguem tem alguma dica? Obrigado.
public static void main(String args[]) throws IOException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String now = sdf.format(new Date());

        Socket socket = new Socket("127.0.0.1", 50010);
        System.out.println("O cliente se conectou ao servidor!");

        PrintStream saida = new PrintStream(socket.getOutputStream());

        // lendo do teclado e escrevendo na socket
        saida.print("codigo da função a ser acionada"+now);
        saida.flush();

        //Declaro o leitor para a entrada de dados
        BufferedReader entrada=null;
        try{
            entrada = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            System.out.println(entrada.readLine());
        }catch(IOException e){
            System.out.println("Algum problema ocorreu para criar ou receber o socket.");
        }finally{
            try{
                saida.close();
                socket.close();
            }catch(IOException e){
            }
        }
    }

3 Respostas

M

O problema que vc está tendo é devido ao uso de BufferedReader.readLine(). Este metodo é blocante - ele irá fazer um block até que seja lido do input um EOL ou EOF.
Em vez disso, faça um trabalho mais manual de ler os caracteres da entrada a medida que forem chegando.
Claro que o buraco pode ser mais embaixo e, na vida real, geralmente é. Na implementação a seguir eu presumo (isso nem sempre é verdade) que a resposta está completa quando não existem mais dados para ler. Acontece que, se o servido ficar dando flush intermediários por algum motivo, vc retomará o seu fluxo de processamento sem que ter lido a resposta completa.
Bom, paremos por aqui por enquanto. QQ dúvida estamos aí.

public static void main(String args[]) throws IOException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String now = sdf.format(new Date());

        Socket socket = new Socket("127.0.0.1", 50010);
        System.out.println("O cliente se conectou ao servidor!");

        PrintStream saida = new PrintStream(socket.getOutputStream());

        // lendo do teclado e escrevendo na socket
        saida.print("codigo da função a ser acionada"+now);
        saida.flush();

        //Declaro o leitor para a entrada de dados
        StringBuilder entrada = new StringBuilder();
        try{
            InputStream in = socket.getInputStream();
            InputStreamReader reader = new InputStreamReader(in);

            char[] cbuf = new char[65536];
            while (in.available() > 0) {
                int length = reader.read(cbuf);
                entrada.append(cbuf, 0, length);
            }

            System.out.println(entrada);
        }catch(IOException e){
            System.out.println("Algum problema ocorreu para criar ou receber o socket.");
        }finally{
            try{
                saida.close();
                socket.close();
            }catch(IOException e){
            }
        }
    }
S

marciosilva1974:
O problema que vc está tendo é devido ao uso de BufferedReader.readLine(). Este metodo é blocante - ele irá fazer um block até que seja lido do input um EOL ou EOF.
Em vez disso, faça um trabalho mais manual de ler os caracteres da entrada a medida que forem chegando.
Claro que o buraco pode ser mais embaixo e, na vida real, geralmente é. Na implementação a seguir eu presumo (isso nem sempre é verdade) que a resposta está completa quando não existem mais dados para ler. Acontece que, se o servido ficar dando flush intermediários por algum motivo, vc retomará o seu fluxo de processamento sem que ter lido a resposta completa.
Bom, paremos por aqui por enquanto. QQ dúvida estamos aí.

Obrigado Marcio resolveu meu problema. Tive que fazer uma gambiarra, pq a resposta do servidor chega alguns segundos depois da requisição, é necessário algumas ações da outra aplicação antes da resposta.
Fiz essa gambirra: while (in.available() == 0 || in.available() > 0) { int length = reader.read(cbuf); entrada.append(cbuf, 0, length); if(entrada.subSequence(1, 2).equals("O")) break; }
Quando chega um caracter comum a todas as mensagens de reposta, entendo que a resposta já foi passada e leio a String inteira.
Caso vc tenha uma solução menos tosca a propor, agradeço. :lol:

Novamente, muito obrigado.

M

Não tem nada de tosca na sua implementação. O que vc fez foi implementar um protocolo cuja especificação determina que o final da mensagem é marcado por esse tal caractere “O”.

Criado 11 de fevereiro de 2011
Ultima resposta 12 de fev. de 2011
Respostas 3
Participantes 2