2013-02-06 2 views
0

Je dispose d'un petit serveur (serveur TCP) qui accepte au maximum 10 connexions sur le port 5000. J'ai créé un socket en mode écoute et j'accepte les connexions. Lorsque l'acceptation réussit, je crée un nouveau thread et gère le trafic dans ce thread. J'ai un client sur la même machine qui est capable de se connecter et de communiquer avec ce serveur.Fermeture active des sockets serveur

Maintenant, pour comprendre TIME_WAIT, je tue mon application serveur en utilisant ctrl + c. Je m'attends à voir les sockets du serveur qui étaient dans l'état "Established" à transférer à "TIME_WAIT". Cependant, quand je fais netstat après la fermeture, je ne vois pas un seul socket dans cet état "TIME_WAIT". Je sais que les prises en mode "écoute" passent directement en état FERMÉ. Mais je suis confus pourquoi les sockets retournés par accept et actuellement dans l'état Established ne sont pas dans l'état TIME_WAIT.

(je suis sur une machine linux et tcp_fin_timeout valeur est à 1min.)

Mon tcpdump ressemble ci-dessous:

localhost.49388 > localhost.5000: 
    Flags [S], cksum 0xfe30 (incorrect -> 0xaa93), seq 3264533269, win 32792, 
    options [mss 16396,sackOK,TS val 20216234 ecr 0,nop,wscale 3], length 0    
localhost.5000 > localhost.49388: 
    Flags [S.], cksum 0xfe30 (incorrect -> 0xc6a0), seq 3352338762, ack 3264533270, win 32768, 
    options [mss 16396,sackOK,TS val 20216234 ecr 20216234,nop,wscale 3], length 0 
localhost.49388 > localhost.5000: 
    Flags [.], cksum 0xfe28 (incorrect -> 0x9fbe), ack 1, win 4099, 
    options [nop,nop,TS val 20216234 ecr 20216234], length 0   
localhost.5000 > localhost.49388: 
    Flags [P.], cksum 0xfe42 (incorrect -> 0xa300), seq 1:27, ack 1, win 4096, 
    options [nop,nop,TS val 20216484 ecr 20216234], length 26   
localhost.49388 > localhost.5000: 
    Flags [.], cksum 0xfe28 (incorrect -> 0x9db0), ack 27, win 4099, 
    options [nop,nop,TS val 20216484 ecr 20216484], length 0   
localhost.49388 > localhost.5000: 
    Flags [P.], cksum 0x0211 (incorrect -> 0x6be1), seq 1:1001, ack 27, win 4099, 
    options [nop,nop,TS val 20216484 ecr 20216484], length 1000    
localhost.5000 > localhost.49388: 
    Flags [.], cksum 0xfe28 (incorrect -> 0x91cb), ack 1001, win 6144, 
    options [nop,nop,TS val 20216484 ecr 20216484], length 0  
localhost.5000 > localhost.49388: 
    Flags [R.], cksum 0xfe28 (incorrect -> 0x8eeb), seq 27, ack 1001, win 6144, 
    options [nop,nop,TS val 20217216 ecr 20216484], length 0 
+0

L'avez-vous essayé avec des clients sur d'autres machines? –

+0

Aucune vérification. Pourquoi serait-ce différent? – user2026599

+0

J'ai essayé entre deux machines et essayé la même procédure. Maintenant, je peux voir les sockets du serveur dans TIME_WAIT. Pourquoi cette différence? – user2026599

Répondre

0

* Mais je suis confus pourquoi les sockets retournés par accepter et actuellement en L'état établi n'est pas dans l'état TIME_WAIT. *

Parce que vous avez tué le processus, empêchant toute sorte d'arrêt ordonné. Vous verrez TIME_WAIT seulement si le processus appelle réellement close() (ou shutdown()) sur une socket - qui enverra un FIN au pair - et restera en vie assez longtemps pour recevoir le ACK du FIN envoyé au pair et au pair FIN (pour lequel un ACK sera renvoyé). Il y a trois façons d'atteindre TIME_WAIT, l'une d'entre elles doit être établie pour TIME_WAIT, mais cela ne peut arriver que si le processus est encore actif pour la transition vers FIN_WAIT1 qui est le début des trois chemins. Votre Ctrl-C a empêché même le close() qui démarre la séquence.

Pour voir TIME_WAIT, vous devrez faire en sorte que votre processus active la fermeture d'une socket, par ex. dans un gestionnaire installé pour SIGHUP, ou via un mécanisme d'entrée. Tuer le processus à tout moment est un bon moyen de ne pas voir ce que vous voulez.

+1

Ce n'est simplement pas vrai. La suppression de la connexion TCP se produit dans le noyau et non dans le userland. –

+0

Bien sûr. Et si vous tuez un processus - au lieu de le faire sortir d'une manière ordonnée - tout ce qui est envoyé par l'autre partie recevra une TVD. – arayq2

+1

Tirez 'tcpdump' et tracez une connexion,'^C' l'un des côtés connectés. Vous verrez un 'FIN' envoyé. La pile de réseau dans le noyau fait cela pour vous (entre autres choses). –