Problema com socket

8 respostas
A

pessoal tenho o seguinte metodo para se comunicar com uma outra maquina atravéz de sockets, no entanto ao menos que a maquina que atua como servidor feche a conexão o andamento do programa fica parado na linha:

retorno = in.readLine();
public Map conecta(String ip, int porta, String msg){
		String retorno = "";
		int cd_retorno = 0;
		
		Socket sok = null;
                PrintWriter out = null;
                BufferedReader in = null;
		
		try{
			
        	sok = new Socket(ip, porta);
                out = new PrintWriter(sok.getOutputStream(), true);
                in   = new BufferedReader(new InputStreamReader(sok.getInputStream()));
        
	        out.println(msg);
	        out.flush();
	        
               //processamento fica travado na linha abaixo
	        retorno = in.readLine();

	        out.close();
	        in.close();
	        sok.close();

        }catch(Exception e){
			cd_retorno = 1;
			retorno = "Erro";
	}

        map = new LinkedHashMap();
	map.put("cd_retorno", cd_retorno);
	map.put("ds_retorno", retorno);

	return map;		
	}

alguma sugestão de como resolver este problema?

8 Respostas

ctosin

alexzr,

Se está travado nesta linha, significa que o cliente está aguaradando o envio de dados por parte do servidor. Você verificou se o seu servidor, depois de receber o conteúdo de msg, usa a output stream dele para devolver uma informação ao cliente?

Você tem que ter algo do tipo lá:

PrintWriter out = new PrintWriter(serverSocket.getOutputStream());
out.println("OK");

Abraço

A

Eu não tenho acesso ao código do servidor, eu estou migrando um programa de power builder para java, no programa original a comunicação não apresenta esse problema

rodrigo.bossini

O funcionamento do método readLine é este.
Ele bloqueia a execução até que receba alguma “input”.
É semelhante ao método readline da classe Scanner.
Quando você o executa, ele fica bloqueado até que algo seja digitado.
É semelhante a função scanf da linguagem C também.
Se você chamou o readLine no cliente, o servidor terá que enviar alguma informação ao cliente, caso contrário ele ficará eternamente bloqueado aí.

A

O readLine recebe um input o problema é que ele fica pendurado até que a conexão seja fechada no servidor.

A conexão está sendo fechada por timout, o q faz com que o processo que deveria durar alguns segundos leve minutos.

ctosin

Se você não espera que o servidor envie nada, não faça a chamada ao in.readLine(), senão seu cliente vai ficar bloqueado.
Recomendo que você procure entender bem o protocolo usado no tráfego dos dados entre os computadores, para que você possa programar de forma correta o envio e espera dos dados.

A

Lembrei de uma coisa que esqueci de mencionar anteriormente.
Na maioria dos exemplos que eu achei na internet para uso de sockets o comando de leitura do socket é feito dentro de uma thread e jogado no system.out.
No entanto como eu necessito processar o valor retornado pelo socket eu não estou fazendo uso de threads.
Outra informação adicional é que esse metodo faz parte de um webservice que roda via jboss.

Quaisquer informações/sugestões são bem vindas

ctosin
Obrigado pelas respostas, e respondendo a sua ultima posso afirmar que o servidor sempre me enviara um retorno, não existe caso em que ele não me envie um retorno.

ctosin

Se o servidor sempre manda uma resposta, tente descobrir exatamente que tipo de resposta é esta. Da maneira como você está fazendo, usando o in.readLine(), você está assumindo que o servidor vai enviar para o cliente uma string seguida de uma quebra de linha. Mas e se o seu servidor não estiver enviando a quebra de linha, ou estiver enviando um outro tipo de dado? Nestes casos o seu método vai ficar bloqueado, até que a string com quebra de linha seja enviada.

Para testar se o servidor está enviando alguma coisa, experimente ler byte por byte da resposta do servidor. Se você conseguir fazer isto, você garante que o servidor está respondendo, mas não da forma como você está esperando.

Como você não tem acesso ao código do servidor, procure analisar o código original (anterior a sua migração) e verifique o que exatamente está sendo mandado pelo servidor.

Abraço

A

ctosin
Consegui resolver o problema, a solução foi pegar o retorno num array de bytes e depois transformar para String.
Muito obrigado pela ajuda

Criado 11 de maio de 2010
Ultima resposta 12 de mai. de 2010
Respostas 8
Participantes 3