Avatar billede dsj Nybegynder
28. juli 2003 - 00:28 Der er 6 kommentarer og
1 løsning

NIO - problem med at lukke forbindelser

Jeg har en server der servicerer en hel del klienter. Når serveren beslutter at lukke forbindelsen til en klient køres følgende metode:

public void disconnect(String reason) {
  synchronized(closeLock) {
    if (connected) {
      connected = false;
      try {
        onClientDisconnect();
      } catch (Exception e) {/* Ignore */}
      try {
        sendMessage(new ResponseMessage("ack", ResponseCodes.ACK_Quit));
        processWrite(-1, -1);
      } catch (Exception e) {/* Ignore */}
      try {
        channel().close();
      } catch (Exception e) { e.printStackTrace(); }
      try {
        key.cancel();
      } catch (Exception e) { e.printStackTrace(); }
      Log.echoDebug("shared.net.Client: Releasing client("+getClientID()+"): "+reason);
    }
  }
}

Jeg kan forsikre at close() kaldes på channel (SocketChannel-instance), og at linien 'shared.net.Client: Releasing client...' udskrives hver eneste gang, MEN forbindelsen lukkes ikke. Det er ikke muligt at sende flere data gennem forbindelsen, men i OS (linux Debian), kan det ses at antallet af forbindelser i tilstanden CLOSE_WAIT vokser og efter omkring 24 timer tillades ikke flere forbindelse og serveren skal genstartes.

Nogen der ved hvad der går galt og hvordan jeg får lukket forbindelserne korrekt? Jeg har prøvet channel.socket().close(), men det ændrer absolut intet.
Avatar billede s.nielsen Nybegynder
28. juli 2003 - 19:34 #1
hvis en socket bliver hængende i CLOSE_WAIT er det ofte fordi den anden side ikke får lukket ordenligt. Hvad gør din klient når serveren lukker sin connection til klienten? Sørg for at klientens socket også lukkes. I henhold til RFC793 (tcp specifikationen) kan man efter man har lukket en connection stadigvæk modtage data, men ikke sende hvilket er konsistent med det du beskriver.
Avatar billede dsj Nybegynder
29. juli 2003 - 19:33 #2
Man kan sagtens lukke forbindelsen fra den ene ende. Hvis serveren tager initiativ til at lukke forbindelsen, skulle problemet meget gerne være skubbet over til klienten.

Når serveren har lukket forbindelsen kan den hverken sende eller modtage data.
Avatar billede s.nielsen Nybegynder
29. juli 2003 - 22:10 #3
>>Man kan sagtens lukke forbindelsen fra den ene ende. Hvis serveren tager >>initiativ til at lukke forbindelsen, skulle problemet meget gerne være >>skubbet over til klienten.
som jeg skrev ovenover mener jeg netop at det er klienten der volder problemer. Måske vi lige skal have klargjort om det er serverens eller klientens connection der ender i CLOSE_WAIT?

>>Når serveren har lukket forbindelsen kan den hverken sende eller modtage >>data.
Den antagelse er ikke korrekt i TCP mæssig forstand, med henvisning til http://rfc.sunsite.dk/rfc/rfc793.html sektion 3.5. Jeg har ikke sat mig ind i hvordan dette er implementeret i java/debian men det undrer mig da hvis de ikke har valgt at følge standarden.

Der er jo tydeligvis et eller andet galt, en connection går ikke i CLOSE_WAIT med mindre den bliver bedt om det, hvilket antyder at ovenstående kode (kaldet til channel.close()) bliver eksekveret. Og det er ganske rigtigt måden at lukke en connection på.
Så lidt kode fra klientsiden også kunne hjælpe med at finde fejlen
Avatar billede dsj Nybegynder
29. juli 2003 - 22:17 #4
Problemet er at jeg ikke har lavet klienten, der er realiseret i Flash og jeg har derfor ikke koden.

Det jeg ikke kan forstå er, at en klient med fejl skal kunne få en server til at gå ned. Serveren må da kunne sige: "nu smider jeg dig af, og så har jeg ikke mere med dig at gøre".
Avatar billede dsj Nybegynder
29. juli 2003 - 22:18 #5
Jeg mindes bare aldrig at have oplevet dette problem da jeg arbejdede med i java "almindelige" servere, der arbejdede med streams og havde en tråd pr. stream.
Avatar billede dsj Nybegynder
30. juli 2003 - 10:55 #6
At indsætte nedenstående kode umiddelbart inden channel().close(); har øjensynligt hjulpet. Der er stadig nogle få forbindelser der bliver der bliver hængende i CLOSE_WAIT, men det er database-forbindelserne, der jo dybest set er TCP-forbindelser!!

Socket socket = channel.socket();
socket.shutdownInput();
socket.shutdownOutput();
socket.close();
Avatar billede dsj Nybegynder
09. august 2003 - 00:01 #7
Lukker.
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester