Ich habe eine Klasse, die einige Methoden besitzt, die im Grunde alle asynchron von irgendwelchen Thread aufgerufen werden können.
Diese Klasse besitzt Client-Objekte, welche sich zu einem Server verbinden.
Nun scheint es, als ob irgendwelche Verbindungen nicht geschlossen werden.
Hat irgendjemand eine Vermutung, wo/wann dies passiert?
Ich muss wahrscheinlich irgenwelche Code-Teile gegen wiedereintritt verriegeln. Aber wo?
Hier ein Auszug aus dem Code:
Nachdem ich 2-3 Mal die Verbindung zum Server gewollt verhindere, stellt das Objekt dieser Klasse automatisch wieder eine Verbindung her.
Beim 3. oder 4. Mal schafft er es nicht mehr, da der Server keine Clients mehr annimmt. Also wurde irgendwelche Clients nicht ordentlich vom Server getrennt.
Ich habe es überprüft. Der Client wird so ordentlich geschlossen:
client.disconnect();
client = null;
Ich verstehe das ganze irgendwie nicht.
Kann mir vielleicht jemand helfen, dieses Rätsel zu lösen? ^^"
Diese Klasse besitzt Client-Objekte, welche sich zu einem Server verbinden.
Nun scheint es, als ob irgendwelche Verbindungen nicht geschlossen werden.
Hat irgendjemand eine Vermutung, wo/wann dies passiert?
Ich muss wahrscheinlich irgenwelche Code-Teile gegen wiedereintritt verriegeln. Aber wo?
Hier ein Auszug aus dem Code:
Code:
public class EngelDataProviderTimerTaskCC200 extends
EngelDataProviderTimerTaskBase
{
// Connection
private String m_Ip = null;
private RpcSvNetworkClient m_svNetworkClient = null;
private RpcSystemNetworkClient m_systemNetworkClient = null;
private RpcSaNetworkClient m_SaNetworkClient = null;
private ConnectingThread m_ConnectingThread = null;
// Sync/Lock Obejcts
private final Object m_PeterOutSync = new Object();
// ###################################################
// ############# OVERRIDE METHODS ####################
@Override
public void start(String ip, int port, String user, String pw)
{
fireInformationOverErrorListener("start(). start main cc200 timer/timertask.");
// configure ip
this.m_Ip = ip;
// start this timer/timertask itself
this.m_RefreshTimer = new Timer();
this.m_RefreshTimer.schedule(this, 0, m_MainTaskRefreshTime);
}
@Override
public void stop()
{
fireInformationOverErrorListener("stop(). try to disconnect. stop every timer/timertask.");
// stop all the other timertasks/timers and set them to null
stopAllTasks();
// stop this timertask+timer itself
m_RefreshTimer.purge();
m_RefreshTimer.cancel();
this.cancel();
// disconnect
this.disconnect();
synchronized (m_PeterOutSync)
{
return;
}
}
@Override
public boolean isConnected()
{
fireInformationOverErrorListener("isConnected(). update connection state.");
// update connection state
setConnectionStateOnValidKeepAlive();
return m_IsConnected.getConnectionState();
}
}
// ############# TIMERTASK MAIN METHOD ##########################
/**
* Tries to connect if not connected. Tries to send a regular keep alive if
* connected.
*/
@Override
public void run()
{
synchronized (m_PeterOutSync)
{
try
{
// if not connected, try to connect
if (!m_IsConnected.getConnectionState())
{
if (m_ConnectingThread == null)
{
this.connect();
} else if (!m_ConnectingThread.isAlive())
{
this.connect();
}
}
// if connected, try to send a keep alive, if needed.
if (m_IsConnected.getConnectionState())
{
this.sendKeepAliveIfNeeded();
}
} catch (Exception e)
{
fireExceptionOverErrorListener(e);
}
}
}
// ###################################################
// ############# HELPING METHODS #####################
/**
* checks if there is still a connection to the machine and sets connection
* state, depending on the connection.
*/
private void setConnectionStateOnValidKeepAlive()
{
// able to get a valid keep alive?
if (keepAlive())
{
// yes -> connected
m_IsConnected.setConnected();
} else
{
// no -> disconnected
this.disconnect();
m_IsConnected.setDisconnected();
}
m_KeepAliveCounter = 0;
}
/**
* A Thread that tries to connect to an machine with 3 diefferent
* clients.
*/
private class ConnectingThread extends Thread
{
@Override
public void run()
{
m_IsConnected.setDisconnected();
disconnect();
try
{
RpcSystemNetworkClient sy = getSystemNetworkClient();
sy.connect(m_Ip, "?");
RpcSvNetworkClient sv = getSvNetworkClient();
sv.connect(m_Ip, "?");
RpcSaNetworkClient sa = getSaNetworkClient();
sa.connect(m_Ip, "?");
} catch (Exception e)
{
System.out.print("timeout\n");
fireExceptionOverErrorListener(e);
fireExceptionOverErrorListener(new Exception(
"EXEPTION -> could not construct a socket connection. check machine. ip might be wrong."));
fireExceptionOverErrorListener(new Exception(
"EXEPTION -> could not connect. try again immediately."));
disconnect();
return;
}
m_IsConnected.setConnected();
}
}
/**
* Tries to connect some time. Then returns. If it is not connected, when
* returning from connect(), it might connect afterwards(until the
* connecting thread is done).
*/
private void connect()
{
fireInformationOverErrorListener("connect(). try to connect network clients to machine.");
// Start a thread that tries to connect to an Engel machine
m_ConnectingThread = new ConnectingThread();
javax.swing.Timer connectingTimer = new javax.swing.Timer(
m_ConnectingTimeout, null);
connectingTimer.setRepeats(false);
m_ConnectingThread.start();
connectingTimer.start();
System.out.println("start timeout timer");
// if the thread is not done with connecting after some time, return
// from connect().
while (m_ConnectingThread.isAlive() && connectingTimer.isRunning())
{
try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
fireExceptionOverErrorListener(e);
}
}
}
/**
* Disconnect every client connected to a machine.
*/
private void disconnect()
{
try
{
if (m_systemNetworkClient != null)
{
System.out.println("disconnect SY");
if (m_systemNetworkClient.getSocket() != null)
{
m_systemNetworkClient.getSocket().close();
}
m_systemNetworkClient.disconnect();
m_systemNetworkClient = null;
}
if (m_svNetworkClient != null)
{
System.out.println("disconnect SV");
m_svNetworkClient.disconnect();
m_svNetworkClient = null;
}
if (m_SaNetworkClient != null)
{
System.out.println("disconnect SA");
m_SaNetworkClient.disconnect();
m_SaNetworkClient = null;
}
m_IsConnected.setDisconnected();
} catch (Exception e)
{
fireExceptionOverErrorListener(e);
}
}
// ############# GET CLIENT ##########################
/**
* @return returns a new / the current SvNetworkClient.
*/
public synchronized RpcSvNetworkClient getSvNetworkClient()
{
if (m_svNetworkClient == null)
{
m_svNetworkClient = new RpcSvNetworkClient();
}
return m_svNetworkClient;
}
/**
*
* @return returns a new / the current SystemNetworkClient.
*/
public synchronized RpcSystemNetworkClient getSystemNetworkClient()
{
if (m_systemNetworkClient == null)
{
m_systemNetworkClient = new RpcSystemNetworkClient();
}
return m_systemNetworkClient;
}
/**
*
* @return returns a new / the current SaNetworkClient.
*/
public synchronized RpcSaNetworkClient getSaNetworkClient()
{
if (m_SaNetworkClient == null)
{
m_SaNetworkClient = new RpcSaNetworkClient();
}
return m_SaNetworkClient;
}
// ############# KEEP ALIVE ##########################
/**
* sends a "keep alive, if some time has passed.
*/
private void sendKeepAliveIfNeeded()
{
fireInformationOverErrorListener("sendKeepAliveIfNeeded(). send a keep alive, if some time passed.\ntime passed since last keep alive: "
+ (m_KeepAliveCounter * m_MainTaskRefreshTime));
// check if it is time to send a keep alive
if (m_KeepAliveCounter >= m_KeepAliveTime / m_MainTaskRefreshTime)
{
if (keepAlive())
{
this.m_IsConnected.setConnected();
} else
{
this.disconnect();
this.m_IsConnected.setDisconnected();
}
m_KeepAliveCounter = 0;
} else
{
m_KeepAliveCounter++;
}
}
/**
* To keep alive the connections of clients, connected to a machine.
*
* @return returns true, if keep alive was valid/successful.
*/
private boolean keepAlive()
{
fireInformationOverErrorListener("keepAlive(). send a keep alive.");
try
{
// check on an existing socket
if (getSystemNetworkClient().getSocket() == null)
{
fireExceptionOverErrorListener(new Exception(
"EXEPTION -> keepAlive(). no socket available. connection is not alive (anymore)."));
return false;
}
// get some information to keep connection alive
getSystemNetworkClient().getDateTime().getTime();
getSvNetworkClient()
.getItemId("CycleTime.sv_CycleTime.dActvalLast");
getSaNetworkClient().getAlarmInfo();
fireInformationOverErrorListener("keepAlive(). no exceptions occured during sending a keep alive");
return true;
} catch (Exception e)
{
fireExceptionOverErrorListener(e);
fireExceptionOverErrorListener(new Exception("Exc is here!!"));
}
fireExceptionOverErrorListener(new Exception(
"EXEPTION -> keepAlive(). can't get information. might not be connected anymore."));
return false;
}
}
Nachdem ich 2-3 Mal die Verbindung zum Server gewollt verhindere, stellt das Objekt dieser Klasse automatisch wieder eine Verbindung her.
Beim 3. oder 4. Mal schafft er es nicht mehr, da der Server keine Clients mehr annimmt. Also wurde irgendwelche Clients nicht ordentlich vom Server getrennt.
Ich habe es überprüft. Der Client wird so ordentlich geschlossen:
client.disconnect();
client = null;
Ich verstehe das ganze irgendwie nicht.
Kann mir vielleicht jemand helfen, dieses Rätsel zu lösen? ^^"
Zuletzt bearbeitet: