NSA - Non Solo Amiga
SOFTWARE => Linguaggi di programmazione e scripting => Topic aperto da: legacy - 17 Gennaio 2015, 21:55:09
-
dead
-
Purtroppo conosco questo problema. E' un bordello immane, soprattutto quando devi scrivere codice multipiattaforma. :-\
-
Come dice la risposta a serverfault, quel stato è richiesto dal RFC 793 (http://tools.ietf.org/html/rfc793) ed è definito essere di 4 minuti.
Quindi il comportamento è giusto secondo la specifica; se Windows chiude il socket senza attendere quel tempo, allora è un suo errore nell'implementazione.
Se questo problema ti capita perchè stai debuggando l'implementazione del server del tuo protocollo, puoi temporaneamente cambiare porta a ogni prova (tanto dopo i 4 minuti puoi tornare a usare quella iniziale).
Se invece il problema è nel normale utilizzo del tuo protocollo, dovresti cambiarlo in modo che sia il client a iniziare la chiusura, in questo modo il server non deve entrare in TIME-WAIT.
-
Il problema di chiudere brutalmente il socket di listening e renderlo libero è che potrebbe avviarsi un programma immediatamente dopo la terminazione del server, e iniziare a parlare col client che ancora crede di essere connesso al server originale; il timeout serve proprio a garantire che anche l'altra parte abbia ricevuto la conferma della chiusura della connessione.
Un male necessario insomma. :(
-
Ma i 4 minuti non ti garantiscono nulla: è un valore arbitrario che è stato messo lì per mettere una pezza al problema, che rimane irrisolto. E che crea, in ogni caso, altri casini.
-
Ma i 4 minuti non ti garantiscono nulla: è un valore arbitrario che è stato messo lì per mettere una pezza al problema, che rimane irrisolto. E che crea, in ogni caso, altri casini.
Mica devi dirlo a me; dillo a quelli che nel 1981 hanno scritto l'RFC del TCP. :D
L'attesa almeno "garantisce" che l'altro socket, che se proprio per sfortuna non riceve la conferma della chiusura, vada in timeout e si chiuda da solo. Non è la soluzione migliore ma il protocollo è questo.
quindi a maggior ragione la soluzione che ho proposto :D
init <-------------- apre il socket lato server, ci fa la bind, ma non la listen
while(1)
{
open <----------------- fa una listen & accept per un solo client, apre il socket per parlare con il client
….
get
put <------------------ parla con il client, sul socket aperto per parlare col client
peg
...
close <------------------ chiude il socket con cui parlava con il client
}
done <--------------- chiude il socket lato server su cui si metteva in ascolto di connect di possibili client
Eh vabbè, ma questo è IL modo per fare il server (per come sono fatti i socket BSD); se la parte interna del while la metti in una funzione, non viene tutta sta complessità che millanti. :P
Se poi usi REUSEADDR (nota: addr), puoi chiudere e riaprire il server subito senza aspettare il timeout (utile durante lo sviluppo e debug).