Sockets dando algum problema

12 respostas
V

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(); } }

12 Respostas

F

Já experimentou aumentar o tempo de timeout?

V

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.

E

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.

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

L

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!

V

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

V
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();
		}
	}
}
L

Oi,

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

Tchauzin!

V

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

V

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)

E

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();
V

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…

V

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?

Criado 15 de outubro de 2012
Ultima resposta 15 de out. de 2012
Respostas 12
Participantes 5