Cum pentru a forța aproape un soclu în TIME_WAIT?

Am rula un anumit program pe linux care, uneori, accidente. Dacă ai deschis-o repede după aceea, se ascultă pe socket 49201 în loc de 49200 cum a făcut-o prima dată. netstat exe arată că 49200 este într-o stare TIME_WAIT.

Există un program, puteți rula imediat forță care priza se mute din TIME_WAIT de stat?

Comentarii la întrebare (1)
Soluția
/etc/init.d/networking restart

Permiteți-mi să elaboreze. Transmission Control Protocol (TCP) este proiectat pentru a fi un bidirecțională, ordonat, și de încredere protocol de transmisie de date între două puncte de capăt (programe). În acest context, termenul de încredere înseamnă că va retransmite pachetele daca se pierde în mijloc. TCP garantează fiabilitatea prin trimiterea înapoi Confirmare (ACK) pachete înapoi pentru un singur sau o serie de pachete primite de la egal la egal.

Acest lucru duce aceeași pentru semnale de control, cum ar fi încetarea de cerere/răspuns. RFC 793 definește TIMP-stare de așteptare să fie după cum urmează:

TIME-wait - reprezintă așteptare pentru suficient timp pentru a trece pentru a fi sigur telecomanda TCP primit confirmare de conexiune cerere de încetare.

Consultați următoarele TCP diagrama de stare:

TCP este un protocol de comunicare bidirecțională, astfel încât atunci când conexiunea este stabilită, nu există o diferență între client și server. De asemenea, fie se poate apela renunță, și ambele colegii trebuie să fie de acord pe închidere pentru a închide complet este stabilită o conexiune TCP.

Las's de apel primul pentru a apela chit ca active mai aproape, și alte peer pasiv mai aproape. Atunci când activ mai aproape trimite FIN, statul se duce la FIN-wait-1. Apoi primește un ACK pentru trimis FIN și de stat merge la FIN-wait-2. După ce primește FIN, de asemenea, de pasiv, de mai aproape, active mai aproape trimite ACK la FIN și de stat merge la TIME-wait. În caz de pasiv aproape nu a primit ACK la a doua FIN, se va retransmite pachet FIN.

RFC 793 setează TIMPUL de-a dovedit a fi de două ori Maxim Segment de Viață, sau 2MSL. Din MSL, timpul maxim un pachet puteți plimba în jurul valorii de Internet, este situat la 2 minute, 2MSL este de 4 minute. Deoarece nu există nici un ACK pentru un ACK, active mai aproape poate't face nimic, dar sa astepti 4 minute, dacă aderă la protocolul TCP/IP corect, doar în cazul în pasiv expeditorul nu a primit ACK său FIN (teoretic).

În realitate, lipsește pachete sunt, probabil, rare și foarte rare, dacă nu's totul se întâmplă în cadrul LAN sau într-o singură mașină.

Pentru a răspunde la întrebarea cuvânt cu cuvânt, Cum să forța de aproape un soclu în TIME_WAIT?, Eu tot o să-mi răspuns inițial:

/etc/init.d/networking restart

Practic vorbind, mi-ar fi de program astfel încât ignoră TIMP-stare de așteptare folosind SO_REUSEADDR opțiune ca WMR menționat. Ce face mai exact SO_REUSEADDR face?

Această opțiune priză spune kernel-ului că, chiar dacă acest port este ocupat (în TIME_WAIT de stat), du-te și reutilizarea oricum. Dacă este ocupat, dar cu un alt stat, veți primi în continuare o adresă deja în uz de eroare. Acesta este util în cazul în care serverul a fost închis în jos, și apoi repornit imediat în timp ce prizele sunt încă active pe port. Ar trebui să fie conștienți de faptul că dacă orice date neașteptate vine, poate deruta pe server, dar în timp ce acest lucru este posibil, nu este probabil.

Comentarii (5)

Eu nu't știu dacă aveți codul sursă de acel program te're de funcționare, dar dacă așa ai putea stabili doar SO_REUSEADDR prin setsockopt(2) care vă permite să lega pe aceeași adresă locală, chiar dacă priza este în TIME_WAIT de stat (cu excepția cazului în care priza este activ de ascultare, a se vedea socket(7)).

Pentru mai multe informații cu privire la TIME_WAIT stat vedea Unix socket FAQ.

Comentarii (5)

Din câte știu nu există nici o modalitate de a forța aproape priza in afara de a scrie un semnal mai bun handler în programul tău, dar acolo este un /proc fișier care controlează cât de mult timeout nevoie. Fișierul este

/proc/sys/net/ipv4/tcp_tw_recycle

și puteți seta timeout la 1 secundă de a face acest lucru:

echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle 

Cu toate acestea, această pagină conține un avertisment cu privire la posibile probleme de fiabilitate la stabilirea acestei variabile.

Există, de asemenea, legate de fișiere

/proc/sys/net/ipv4/tcp_tw_reuse

care controlează dacă TIME_WAIT prize pot fi refolosite (probabil fără nici un timeout).

De altfel, kernel documentația avertizează să nu pentru a schimba oricare dintre aceste valori, fără 'consiliere/cereri de experți tehnici'. Ceea ce nu sunt.

Programul trebuie să fi fost scris pentru a încerca o legare la portul 49200 și apoi incrementa cu 1 dacă portul este deja în uz. Prin urmare, dacă aveți de control al codului sursă, ai putea schimba acest comportament să așteptați câteva secunde și încercați din nou pe același port, în loc să crească.

Comentarii (3)

De fapt, există o modalitate de a ucide o conexiune - killcx. Ei susțin că acesta funcționează în orice stat de conexiune (pe care nu am verificat). Trebuie să știți de interfață în cazul în care comunicarea se întâmplă totuși, ea pare să-și asume eth0 în mod implicit.

UPDATE: o altă soluție este cutter, care vine în unele distributii linux' centrale de tranzacții.

Comentarii (0)

O altă opțiune este de a utiliza SO_LINGER opțiune cu o temporizare de 0. În acest fel, atunci când închideți priza este închis cu forța, trimițând un PRIM loc de a merge în FIN/ACK închidere comportament. Acest lucru va evita TIME_WAIT de stat, și ar putea fi mai potrivite pentru anumite utilizări.

Comentarii (4)

O soluție alternativă ar fi să avem niște fiabile proxy sau port forwarding-ul, care ascultă pe portul 49200, apoi mai departe conexiunea cu privire la una din mai multe instanțe de mai puțin fiabile programul folosind diferite porturi... HAPROXY vine în minte.

De altfel, portul de legătură este destul de mare. Ai putea încerca, folosind o cantitate neutilizată de o deasupra 0-1024 gama. Sistemul este mai puțin probabil de a utiliza un mai mic număr de port ca un port efemer.

Comentarii (0)

TIME_WAIT este cea mai comună problemă în programarea socket arhitectură client-server. Așteptați câteva secunde, încercând periodic este cea mai bună soluție pentru el. Pentru timp real de aplicații au nevoie de server trebuie să te ridici imediat Există SO_REUSEADDR opțiune pentru ei.

Comentarii (0)