Zivjo,
Takole je, po moje.
Najprej povezava zivi in stvari potekajo v redu. Nato
pa pride signal FIN, ki ga poslje klient, ko hoce koncati
povezavo. Pri tem se klient postavi v stanje WAIT_FIN1.
CLOSE_WAIT je stanje, v katerem je streznik, ko dobi prvi FIN
od odjemalca.
Ko se mu (stezniku) zljubi, poslje v obvestilo o prejemu tega
FINa in ko klient dobi to obvestilo, se (klient) postavi v
stanje WAIT_FIN2.
Nato se streznik postavi v stanje LAST_ACK in
poslje klientu novi FIN. Klient se, ko dobi ta drugi FIN,
postavi v TIME_WAIT. Klient poslje se obvestilo o drugem FINu,
in streznik gre v CLOSED.
Ascii art:
odjemalec streznik
FIN
WAIT_FIN1 |-------------->| CLOSE_WAIT
| ack |
| /-----------|
WAIT_FIN2 |<-/ |
| FIN |
TIME_WAIT |<--------------| LAST_ACK -- tega FINa tebi ne poslje
| |
| ack |
|-------------->| CLOSED
Moje mnenje:
Tebi torej streznik ne poslje drugega FINa,
zato ostaneta vsak v svojem stanju. Za vecno.
Ta problem je znan in opisan v literaturi, vendar
ga vecina implementacij TCP-ja obide s *krsitvijo TCP
protokola*, ko uvede 'timer'. Tak je tudi moj Linux
doma. Uspel sem priti do situacije, podobne tvoji z
navadnim telnetom, ampak se je stvar ravno z iztekom
dolocenega casa resila ven.
* Poskusi z novim jedrom (kernelom). Moj je 2.2.12
* Mogoce prehitro pobijes streznisko nit? O tem ne vem
kaj dosti, zato le ugibam.
Glede TIME_WAIT:
TIME_WAIT je stanje, v katerem poslje klient zadnji ack,
traja pa 2x toliko, kolikor lahko zivijo IP paketi.
Zakaj? Ker lahko da se zadnji ack pac nekje izgubi,
streznik ponovno poslje FIN, zato mora klient se 1x
poslati zadnji ack.
Ta cas je pri linuxu 1 minuta. Ko bo tvoj odjemalec
v TIME_WAIT, je po moje ze vse v redu, slej ko prej bo
povezava padla in suck-it se bo zaprl. Najbrz ;-)
Se CLOSED, CLOSE... v knjigah tudi recejo FIN_WAIT_2
ipd., pa je to enako kot WAIT_FIN2 po moje.
lp, matevz