Sockets dando algum problema

Pessoal, estou com um problema aqui, eu ja postei sobre isso no forum mas a solucao que me apresentaram parece que não surgiu efeito para correção do bug.

Metodo de comunicação: Sockets
Estrutura fisica: Wireless LAN

O problema é que fica dando ReadTimeOut toda hora e as vezes segue de ConnectionRefused, e não é problema de interrupção no sinal, por que já testei no cabo também e sem solução (todos os metodos estão em sincronia, ja verifiquei e não esta acotnecendo um deadlock)
Uma maneira de contornar esse problema foi a inserção de um reconnect toda vez que da um desses erros, mas o problema é que TODA hora da esse problema…

O programa está assim:
Possuo uma classe interna que fica lendo os dados o tempo todo, esse processo é feito escrevendo uma mensagem no socket e lendo a resposta.

public synchronized void connect(String ip, int port) { try { InetSocketAddress inet = new InetSocketAddress(ip, port); socket = new Socket(); socket.connect(inet, 2000); socket.setSoTimeout(2500); in = socket.getInputStream(); out = socket.getOutputStream(); } catch (IOException e) { e.printStackTrace(); } }

Já experimentou aumentar o tempo de timeout?

Sim, já experimentei.
O timeout esta suficiente para ler os dados, são strings pequena de no max 50 caracteres e a comunicação é direta, não há interrupção no sinal, até no cabo acontece no mesmo problema.

[quote=Vinicius Zibetti Resko]Sim, já experimentei.
O timeout esta suficiente para ler os dados, são strings pequena de no max 50 caracteres e a comunicação é direta, não há interrupção no sinal, até no cabo acontece no mesmo problema.[/quote]

O dispositivo que fornece as strings que você vai ler usa corretamente os comandos do socket TCP (shutdown)?

Oi,

Você vai precisar postar o seu método Send e Receive. Postar apenas o connect (que por sinal deveria ser chamado apenas 1 vez) não basta.

Tchauzin!

Você deu o comando setTcpNoDelay(true) em seus sockets? Caso contrário, com pacotes pequenos assim, você pode estar esbarrando no algoritmo de Nagle.

[code]package com.network;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

public class EthernetComm {

private InputStream in;

private OutputStream out;

private byte[] buffer = new byte[2048];

private Socket socket;

public synchronized void connect(String ip, int port) {
	try {
		InetSocketAddress inet = new InetSocketAddress(ip, port);
		socket = new Socket();
		socket.connect(inet, 2000);
		socket.setSoTimeout(2500);
		in = socket.getInputStream();
		out = socket.getOutputStream();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

public synchronized void disconect() {
	try {
		this.socket.close();
		this.out.close();
		this.in.close();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

public synchronized String readFromPort() {
	int data;
	String ret = "";
	try {
		int len = 0;
		while (true) {
			data = in.read();
			if ((data > -1)) {
				if (data == '\n' || data == '\r') {
					break;
				}
				buffer[len++] = (byte) data;
			} else {
				break;
			}
		}
		ret = new String(buffer, 0, len);
		sleep(15);
	} catch (IOException e) {
		e.printStackTrace();
	}
	return ret;
}

public synchronized void writeOnPort(String message) {
	if (message.length() > 0) {
		try {
			int n = message.length() + 2;
			byte[] ascii_v = new byte[n];
			ascii_v[n - 1] = 10;
			ascii_v[n - 2] = 13;
			for (int i = 0; i < n; i++) {
				if (i < n - 2)
					ascii_v[i] = (byte) message.charAt(i);
				this.out.write(ascii_v[i]);
			}
			this.out.flush();
			sleep(15);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

private void sleep(long ms) {
	try {
		Thread.sleep(ms);
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
}

}[/code]

Oi,

A mensagem é apresenta em qual lado? Client ou Server? Poderia postar o stack inteiro ?

Tchauzin!

ViniGodoy, eu ja testei, inclusive ja estudei bastante sobre esse algoritmo, e como ele funciona, mas continuava dando os erros.

Funciona assim:

  1. Eu gero uma string através de um protocolo aqui.
  2. Envio essa mensagem por meio do socket.
  3. O equipamento verifica a string e devolve uma resposta para o socket.

Segue stack trace:

java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(Unknown Source) at java.net.SocketInputStream.read(Unknown Source) at java.net.SocketInputStream.read(Unknown Source) at com.network.EthernetComm.readFromPort(EthernetComm.java:120) at com.view.Main$Reading.run(Main.java:817)

Vinicius, você não configurou o socket para usar a opção TcpNodelay. Faça isso o mais rápido possível - porque como as mensagens são muito pequenas, e você tem um protocolo “chatty” (ou seja, você manda uma mensagem pequenininha e quer uma resposta imediatamente) então você precisa setar o tcpnodelay para true. Siga o que seu xará Vinicius Godoy lhe recomendou. Deixar isso não afeta em nada o desempenho, já que seu protocolo é “chatty”. Se você tivesse um protocolo do tipo “as mensagens de entrada são independentes das mensagens de saída” você então deveria setar o tcpnodelay para false (que é o default).
O seu código, que está abaixo, não seta o tcpnodelay para true explicitamente. Você tem de setar isso explicitamente.

            InetSocketAddress inet = new InetSocketAddress(ip, port);  
            socket = new Socket();  
            socket.connect(inet, 2000);  
            socket.setSoTimeout(2500);  
            in = socket.getInputStream();  
            out = socket.getOutputStream(); 

entanglement , eu ja testei aqui ativar o tcpnodelay, infelizmente o erro persiste.
O que está acontecendo é que ele esta lendo normalmente ai do nada ele da um timeout, ai reconecta, ai le mais algumas vezes, ai da erro de novo e assim vai…

Quem está do outro lado da conexão? É uma aplicação sua ou de terceiros?
Já rodou no wireshark para ver se o outro lado não está abandonando a conexão?