31. juli 2003 - 10:08Der er
40 kommentarer og 1 løsning
timeout på socket (ssl socket - hvis det har nogen betydning)
Hejsa, hvordan kører man en time out på en socket, således at hvis der ikke har været noget trafik i fx 20 sek, så bliver en socket.close() afviklet på serveren?
Jeg har aldrig arbejdet med timeout før, så en lille forklaring vil være glimrende...
Bare søgningen snart var vel fungerende på exp igen..
Jeg ved ikke om du kan få det lavet i selve Socket klassen, men du kan gøre det i din applikation.
Du wrapper Socket i en klasse som også har en long lastActivity. Hver gang der er nogen aktivitet så sætter du den til System.currentTimeMillis. Så laver do en cleanup thread der kigger på alle objekterne og sammenligner System.currentTimeMillis med lastActivity og hvis den er for gammel så lukkes socket.
Hej Arne, Jeg er med på hvad du mener, så det går jeg straks i krig med! Men jeg har da lige et spg. (og måske flere dukker op ;o) Hvad vil det sige at wrappe?
En wrapper klasse er en klasse som kun er en indpakning til en anden klasse og enten tilføjer ganske lidt funktionalitet eller et simplere interface.
Jeg kalder det her en wrapper klasse omkring Socket, fordi reelt ligger al funktionalitetent jo i Socket. Vi skal bare lige notere os tidspunktet for last activity.
Du må så selv afgøre om wrapper klassen skal extende Socket eller skal indeholde en referance til Socket.
Okey, så tror jeg at jeg er med. Så er der altså ikke noget i vejen for at sende en reference til mit socket-arrayet med over i tråden (wrapper-klassen)? Tror det bliver den løsning.
Jeg forestillede mig noget i retning af at: - du lavede en wrapper klasse for Socket - du erstattede dit Socket array med et wrapper klasse array - den cleanup tråd fik en referance til array med over i constructor
wrapper klassens read laver så bare en socket read og updaterer last activity,
[det er nok nemmest hvis wrapper klassen indeholder både Socket og in og out streams]
Okey, så havde jeg misforstået helt. Jeg havde bare tænkt mig at starte en tråd når server-programmet starter. Tråden skulle så have en reference til mit socket-array og hele tiden løbe det igennem for at se om nogle connections skal lukkes. Men det var så ikke lige det du mente.
dvs. jeg laver en:
public class TimeOutSSLSocket extends SSLSocket{ }
private long lastActivity;
public TimeOutSSLSocket(ServerSocket serverSocket){ SSLSocket socket = (SSLSocket).serverSocket.accept(); }
public setLastActivity(){ lastAcivity = System.currentTimeMillis() }
public long int getLastAcivity(){ return lastActivity; }
Nope du snakker ikke sort :o) Jeg var bare i tvivlom hvad jeg skulle gøre med read og write, men du ville altså bare lave en read til hver af de forskellige typer (ObjectInputStream input, DataInputStream in):
public int read1 (byte[] b){ int res = input.read(b); lastActivity = System.currentTimeMillis(); retrurn res; }
public int read2 (byte[] b){ int res = in.read(b); lastActivity = System.currentTimeMillis(); retrurn res; }
lige en anden ting, hvad er grunden til at du returner res? far man en 1 hvis read gik ok, og en -1 hvis det slog fejl?
D.v.s jeg ville lade min wrapper klasse supportere en af følgende: InputStream/OutputStream DataInputStream/DataOutputStream ObjectOutputStream/ObjectInputStream BufferedInputStream/BufferedOutputStream men kun en.
Forrygende Arne :o) I de baner havde jeg da godt nok overhovedet ikke tænkt...
Men nu er et nyt "problem" opstået. Når jeg nu skal tilgå nogle at de metoder som ligger i socket burde jeg så ikke bare kunne kalde dem direkte på mit TimeOutSSLSocket objekt? istedet for timeOutSSLSocket.socket.close() ?
Jeg kan godt extende Socket, men får fejl hvis jeg extender SSLSocket...
fejl: TimeOutSSLSocket should be declared abstract; it does not define getEnableSessionCreation() in javax.net.ssl.SSLSocket public class TimeOutSSLSocket extends SSLSocket{
hvorfor skal den erklæres abstract når den ikke skal ved socket?
Forrygende Arne, nu virker det perfekt :o) Jeg fandt dog ud af at hvis jeg skulle sende mere end et objekt var jeg nød til at have output = new ObjectOutputStream (sslSocket.getOutputStream()); i write metoden istedet for construkteren. Jeg forstår ikke hvorfor, men ja, sådan skal det altså være!
Så skal cleanup-threaden laves, men er det ikke lidt vildt hvis den ikke laver andet end konstant at stå og kigge på om der er tiden er overskredet? Kan man ikke/er det ikke bedre, at lave den sådan, at den sleeper i 5 min og så igen ser efter om der skal cleanes op?
private long lastActivity; public SSLSocket sslSocket; private ObjectInputStream input; private ObjectOutputStream output;
public TimeOutSSLSocket(SSLSocket sslSocket){ this.sslSocket = sslSocket; }
public Object read(){ try{ input = new ObjectInputStream (sslSocket.getInputStream()); Object temp = input.readObject(); //castet er flytte ud! dvs. til klassen der opretter en instans af denne (X x = (X)sockwrap.read();) lastActivity = System.currentTimeMillis(); return temp; } catch (IOException IOex) { System.err.println("Noget galt med getInputStream eller getOutputStream."); System.err.println(IOex); } catch(Exception e){ System.out.println("Exception i TimeOutSSLSocket.java's read()"); e.printStackTrace(); } return null; }
public void write(Object o){ try{ output = new ObjectOutputStream (sslSocket.getOutputStream()); output.writeObject(o); output.flush(); lastActivity = System.currentTimeMillis(); } catch(Exception e){ System.out.println("Exception i TimeOutSSLSocket.java's write()"); e.printStackTrace(); } }
public boolean inaktiv(){ if((System.currentTimeMillis()-lastActivity)>20*60*1000) return true; else return false; }
Men hvis man kun har dem i konstrukteren, så får jeg en fejl anden gang den skal til at læse fra socketen, fejl lyder på java.io.StreamCorruptedException og kommer på denne linie: Object temp = input.readObject(); fra read() Men jeg undgår altså fejlen hvis jeg henter objectoutputstream hvergang.
Er reset iøvrigt en tung funktion siden du kun vil kalde den hver 100 gang?
Det er vist ved at være på tide at du får dine point arne. Du skriver "Hvis du får memory problemer, så kald reset på ObjectOutputStream for hver 100. write." Hvad med read? hvis den ikke skal reset'tes(altså på serverside), hvor i ligger forskellen så?
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.