[Linuxtrent] Re: OT: Socket [Programmazione]

  • From: Marco Cova <marco.cova@xxxxxxxxxxxxxxx>
  • To: linuxtrent@xxxxxxxxxxxxx
  • Date: Fri, 9 Apr 2004 15:03:13 +0200

Scrive Nivox <zito.andrea@xxxxxxxxxx>:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Alle 11:26, venerdì 9 aprile 2004, marco moser ha scritto:
> > ho avuto anch'io lo stesso problema che ho risolto guardando
> > i sorgenti di apache 1.3.*
> >
> > non ti spaventare, e' semplice e l'apertura di una socket e' una
> > parte ben incapsulata (grep TIME_WAIT)
> 
> Grazie mille per il consiglio... appena ho un pelo di tempo mi doterò
> dei sorgenti e di una bella dose di pazienza :-S.

Mah, studiare i sorgenti di apache non ti guasterà senz'altro, ma non è che sia
poi così necessario, almeno in questo caso... ;-)

Il mio consiglio (sostanzialmente un riassunto di quanto già detto dagli altri) 
è:
a) Se vuoi semplicemente risolvere il problema, imposta, come ti è stato detto,
l'opzione SO_REUSEADDR sulla socket. Attenzione che devi farlo _prima_ di fare
il binding della socket. Nota che l'invocazione di setsockopt è un po' diversa
da come ti è stata riferita. In particolare, dovrai fare qualcosa di simile a:

const int on = 1;
setsockopt(sockdf, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
e controlla il valore di ritorno: non fa mai male.

b) Se vuoi capire cosa sta succedendo, allora sì ti servirà un po' più di 
pazienza:
*) procurati una copia del diagramma degli stati del TCP
[http://www4.informatik.uni-erlangen.de/Projects/JX/Projects/TCP/tcpstate.html]
e cerca di capire qual è la relazione tra le varie transizioni di stato e le
funzioni della socket API
*) leggi la RFC 1337 per capire a cosa serve lo stato TIME_WAIT:
http://www.ietf.org/rfc/rfc1337.txt
*) corri in biblioteca e procurati una copia di R. W. Stevens, UNIX Network
Programming, e leggi (almeno) i paragrafi dedicati a questo argomento (capitolo 
7).

Ultima nota: _non_ vuoi controllare che il "kernel abbia effettivamente finito
di fare il suo lavoro", proprio perché è lavoro del kernel e non
dell'applicazione. Elaborando un po': quando sei nello stato TIME_WAIT, sei
certo che tutti i dati che dovevi trasmettere sono stati trasmessi e ACKed dal
peer[1] e viceversa (in termini di protocollo, hai inviato una FIN e ricevuto la
corrispondente ACK e viceversa). 

Marco

[1] Per pignoleria: dallo stack TCP/IP del peer piuttosto che dall'applicazione
impegnata nella connessione. Che può essere una distinzione importante in alcuni
casi ma questa è un'altra storia/faq...

-- 
Per iscriversi  (o disiscriversi), basta spedire un  messaggio con OGGETTO
"subscribe" (o "unsubscribe") a mailto:linuxtrent-request@xxxxxxxxxxxxx


Other related posts: