# Wie connection Reset abfragen/abfangen?



## TobiTobsen (15. Jun 2009)

Hi,
in meiner Software baue ich eine Socket verbindung zu einem Server auf. 
Läuft alles über statische IP´s in einem lokalen Netzwerk.

Das läuft soweit alles ganz gut, allerdings wird tauch nach einer gewissen Zeit in der nichts gesendet wird eine Conection Reset Exceptionn (java.net.SocketException: Connection reset) auf sobald wieder etwas gesendet wird. 

Es ist so das ich Daten sende und dann den gegenüber noch mal abfrage ob er den neuen Befehl übernommen hat. 
Also erst neue Daten senden, dann abfragen. Und nur beim abfragen taucht diese Exception auf, nicht beim schreiben...

Kann mir jemand sagen wie ich die abfragen kann ob die Verbindung noch besteht oder ein reset ausgeführt wurde? Mit socket.isconnected() klappt es leider nicht.


Viele Grüße,
Tobi


----------



## Kaffeebohn (18. Jun 2009)

Wieviel Zeit liegt denn zwischen dem senden und dem abfragen? Schließt du evtl. einen Stream wodurch die Verbindung beendet wird?


----------



## TobiTobsen (19. Jun 2009)

Es wird gesendet und sofort danach wird der neue Status geprüft...


----------



## Kaffeebohn (19. Jun 2009)

Ohne Quellcode kann ich dir da leider nicht weiterhelfen. Vielleicht kannst du paar Ausschnitte posten?


----------



## TobiTobsen (24. Jun 2009)

Hier mal etwas aus meiner Klasse in der die Socketverbindung aufgebaut wird

[Java]
	/**
	 * Konstuktor
	 */
	public EthernetIO (String ipAdress, int portNumber){
		logger =  Logger.getLogger(EthernetIO.class);
		this.ipAdress = ipAdress;
		this.portNumber = portNumber;

		pos = new PipedOutputStream();
		openSocket();

		try {
			socket.setKeepAlive(true);
		} catch (SocketException e1) {

			e1.printStackTrace();
		}

	}



	/**
	 * Stellt Socketverbindung her. 
	 */
	public void openSocket(){

		try {
			System.out.println(ipAdress + "  " + portNumber);
			socket = new Socket (ipAdress, portNumber); 
			System.out.println("Socket connected?: " + socket.isConnected());
		} catch (UnknownHostException exc) {
			logger.warn(exc.getMessage());
			exc.printStackTrace();
		}
		catch (IOException e) {
			logger.warn(e.getMessage());
			e.printStackTrace();
		}


		try {
			outStream = socket.getOutputStream();
			inStream = socket.getInputStream();

		} catch (IOException e1) {
			logger.warn(e1.getMessage());
			e1.printStackTrace();

		}	
	}



	/**
	 * Schließt die Socketverbindung
	 */
	public void closePorts (){
		try {
			outStream.close();
			inStream.close();
			socket.close();
			System.out.println("Socket Closed");
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();

		}
	}


[/Java]


Nach einer gewissen Zeit in der die Kommunikation ruht, fliegen mir die Exceptions nur so um die Ohren. Meistens Connection Reset...
Fiese Sache.

Vielen Dank schon mal im Vorraus!


edit:

StackTrace:

[Java]
java.net.SocketException: Connection reset
	at java.net.SocketInputStream.read(Unknown Source)
	at java.net.SocketInputStream.read(Unknown Source)
	at mdc.controller.EthernetIO.readSingleByte(EthernetIO.java:301)
	at mdc.controller.barco.test.main(test.java:56)
[/Java]


----------



## tuxedo (26. Jun 2009)

Sieht soweit ganz okay aus. Bis auf den setKeepAlive() Aufruf würd' ich's genauso machen. 

Ein paar Fragen hab ich aber noch:

* Was für ein Server ist das? Hast du den Code-technisch selbst unter Kontrolle? 
* Wielange liegt die Verbindung brach bevor der ConnectionReset auftritt? Ist die Zeit immer gleich oder variiert diese?

Generell: Abfragen, ob die Verbindung noch steht oder "funktioniert" kannst du nicht ohne etwas Eigenaufwand. Der Link hier hat mir vor einiger Zeit geholfen: socket : Java Glossary

Mein Fazit: Ich schicke, wenn die Verbindung in einen Idle-Zustand gerät in einem bestimmten Interval eine "Ping" Nachricht an mein Gegenüber, welcher innerhalb einer bestimmten Zeit mit "Pong" antworten muss. Kommt die Antwort nicht, bzw. spät, dann kann ich davon ausgehen dass die Verbindung gestört ist, bzw. nicht mehr existiert. 

Gruß
Alex

P.S. Für was steht denn das "barco" in dem Packagenamen? Nicht zufällig für eine Firma mit Stammsitz in Belgien?


----------



## TobiTobsen (26. Jun 2009)

Hi Alex,
danke für deine Infos.

Warum würdest du den setKeepalive nicht machen?
Ich dachte immer das ich dadurch verhindere das mein gegenüber die Verbindung nach seinem Timeout kappt.

- der Server gegenüber hab ich nicht unter Kontrolle. Er macht das was er für richtig hält :-(.
- Die Zeit konnte ich bisher noch nicht wirklich herausfinden. Der Fehler tritt gefühlt erst nach 2-3h Stunden auf.

Den Link werde ich mir mal anschauen,danke.

Ja hat was mit der belgischen Firma zu tun .

Grüße


----------



## tuxedo (26. Jun 2009)

TobiTobsen hat gesagt.:


> Hi Alex,
> danke für deine Infos.
> 
> Warum würdest du den setKeepalive nicht machen?



Naja, du hast keinen Einfluss darauf wann ein KeepAlive gesendet wird. Wirklich "brauchen" konnte ich die Einstellung deshalb bis jetzt noch nicht. Mein eigenes PingPong ist da etwas transparenter.



> Ich dachte immer das ich dadurch verhindere das mein gegenüber die Verbindung nach seinem Timeout kappt.



Schau mal in den Link. Da sollte das beschrieben stehen.



> - der Server gegenüber hab ich nicht unter Kontrolle. Er macht das was er für richtig hält :-(.
> - Die Zeit konnte ich bisher noch nicht wirklich herausfinden. Der Fehler tritt gefühlt erst nach 2-3h Stunden auf.
> 
> Den Link werde ich mir mal anschauen,danke.



Tritt der Fehler wirklich nach 2-3h "idle" auf, oder auch "einfach mal so kurz nachdem etwas gesendet wurde"?
Im ersten Fall würde ich drauf tippen, dass der Server timeout-technisch die Verbindung kappt. Könnte sein, dass der "einseitige Keep alive" den Server nicht wirklich interessiert. 
Kannst du denn "dummy anfragen" schicken um die Verbindung nicht zu lang im "idle" Zustand zu lassen?



> Ja hat was mit der belgischen Firma zu tun .



Na dann sind wir Kollegen: WhoIsWho -> achr 

Gruß
Alex


----------



## TobiTobsen (26. Jun 2009)

Ja Fehler tritt wirklich nur nach ein paar Stunden auf...
Ich werde das mit den Dummy-Messages noch mal testen. 

Also ich bin nicht von Barco, arbeite nur mit deren Produkten. 
und du bist von Barco?


----------



## tuxedo (26. Jun 2009)

> Ja Fehler tritt wirklich nur nach ein paar Stunden auf...
> Ich werde das mit den Dummy-Messages noch mal testen. 

Denke das sollte helfen.
Was mir dazu noch eingefallen ist: MySQL JDBC: Da hat man in der Standardkonfiguration ein ähnliches Problem: Baut man eine Verbindung zur DB auf und benutzt diese lange Zeit nicht, fliegt einem alles um die Ohren wenn man sich nach Stunden doch wieder dafür entscheidet eine Abfrage zu schicken.
Da hilft dann auch nur JDBC/MySQL so einzustellen dass die Verbindung nicht gekappt wird, ODER regelmäßiger Anfragen zu stellen, damit die Verbindung gar nicht erst "herum idle't".

> Also ich bin nicht von Barco, arbeite nur mit deren Produkten.

Ah, okay. So rum geht's natürlich auch 

> und du bist von Barco? 

So ist es.


----------



## tuxedo (26. Jun 2009)

Zu KeepAlive auf Socketebene in Java:

Java 2 Platform SE v1.3.1: Interface SocketOptions



> When the keepalive option is set for a TCP socket and no data has been exchanged across the socket in either direction for *2 hours (NOTE: the actual value is implementation dependent)*, TCP automatically sends a keepalive probe to the peer. This probe is a TCP segment to which the peer must respond. One of three responses is expected:
> 1. The peer responds with the expected ACK. The application is not notified (since everything is OK). TCP will send another probe following another 2 hours of inactivity.
> *2. The peer responds with an RST, which tells the local TCP that the peer host has crashed and rebooted. The socket is closed. *
> 3. There is no response from the peer. The socket is closed. The purpose of this option is to detect if the peer host crashes. Valid only for TCP socket: SocketImpl



Bei dir scheint Fall 2 einzutreten. Und offenbar lässt der Server die Verbindung fallen BEVOR dein Client ein KeepAlive sendet. 
Um eine Art PingPong (bzw. eine Dummy-Anfrage an den Server) wirst du nicht herum kommen wenn die Verbindung dauerhaft "online" bleiben soll.


- Alex


----------

