• 10 odgovora
  • 8.247 pregleda
Kako da zatvorim socket i nateram accept() da vise ne ceka? 05.09.2002. u 19:34 · pre 293 meseci #1
Kada kreiram socket i bindujem port, znaci socket(), bind(), pa listen(),
kako posle da prekinem slusanje porta, odbindujem port i zatvorim socket?

I jos nesto, imam accept() koji ceka u glavnoj niti.
Kada hocu da ugasim server (znaci zatvorim sve konekcije ka klijentima),
kako da nateram accept() da ne ceka vise? :)
Re: Kako da zatvorim socket i nateram accept() da vise ne ceka? 05.09.2002. u 20:31 · pre 293 meseci #4
accept će naravno uvek da blokira, osim ako ne koristiš non-blocking sockets. Kako zamišljaš da zaustaviš server? Nekom komandom od strane klijenta, ili neki drugi način? Ja sam radio sa Windows NT service-ima i tamo se serveri startuju i zaustavljaju preko SCM-a. Možeš li malo preciznije da opišeš taj tvoj server?
Potpis
IOCC
Re: Kako da zatvorim socket i nateram accept() da vise ne ceka? 05.09.2002. u 23:40 · pre 293 meseci #5
Linux server sa nitima.
Pri start-upu se otvori START_THREADS thread-a (taj broj je 5 po default-u), i te niti spavaju i cekaju da ih glavna nit, gde se nalazi accept, zaposli.
Ako ponestane slobodnih threadova, otvaraju se novi, sve do MAX_CLIENTS, a ako novootvoreni threadovi (znaci oni koji su se otvorili kada je onih 5 bilo zauzeto) spavaju duze od 15 min (MAX_SLEEP_TIME je po defaultu 900 sec - 15 min) - oni se zatvaraju.

Jel' sam sad objasnio?
Re: Kako da zatvorim socket i nateram accept() da vise ne ceka? 06.09.2002. u 02:10 · pre 293 meseci #6
To je OK, ali sam više pitao kako izgleda sa user stanovišta. Kako si zamislio da kontrolišeš događaje kao što su pause/resume i stop? Koliko kapiram sve niti su ti zauzete (glavna "slušanjem", a radne ili spavaju ili obrađuju zahteve). Kako misliš da administrator komunicira sa serverom?
Potpis
IOCC
Re: Kako da zatvorim socket i nateram accept() da vise ne ceka? 06.09.2002. u 11:51 · pre 293 meseci #7
Nisam spomenuo keyboard thread :)
Dakle, kada ukucam exit, iz keyboard thread-a se zovne f-ja server_shutdown(), koja pozatvara sve otvorene konekcije, i pogasi sve thread-ove (prvo ih probudi sa mutex_unlock, pa oni sami izadju, znace NE ubijam ih).
Kad se konekcije zatvore, thread-ovi pogase, onda izadjem i iz keyboard thread-a, znaci ostane mi samo glavna nit, i to je to, tu me ceka accept() :)

Ili da accept stavim u poseban thread, pa da ga kill-ujem, ili da napravim klijent unutar samog servera koji ce da odblokira accept (ovo zvuci skroz sasavo :)).
E, mene interesuje postoji li neko elegantnije resenje?

Ne pravi mi se poseban thread samo za accept, jer vec imam i keyboard thread, i plus 5 threada koji po defaultu cekaju klijenta...
Re: Kako da zatvorim socket i nateram accept() da vise ne ceka? 06.09.2002. u 13:01 · pre 293 meseci #8
Mogao bi da koristis non-blocking listening socket, pa ispred accept-a da stavis jedan select. Tada ce listening thread da se zakuca na select.
E select mozes da prekines bilo kojim signalom koji nije blokiran (tu situaciju mozes da prepoznas kad select vrati EINTR).
Re: Kako da zatvorim socket i nateram accept() da vise ne ceka? 08.09.2002. u 02:10 · pre 293 meseci #10
Evo jednog nacina:
Pre nego sto kreiras thread-ove iz pool-a i udjes u accept loop stavi sledeci kod:
- pokupi pid onog thread-a gde ti je accept (sa getpid)
- postavis signal handler npr. za SIGUSR1 (funkcijom signal).

U signal handler stavis kod koji ce postaviti jedan flag (najbolje u volatile promenljivoj) koji ce reci 'treba ugasiti listening socket'.
Prilikom sledeceg select-a koji vrati <0 i pri tome bude errno==EINTR i ovaj flag postavljen na kraj==true izadjes iz select/accept petlje i zatvoris socket.

Sada neko ko hoce da prekine accept/select petlju posalje signal SIGUSR1 thread-u koji ima pid==onaj zapamceni sa pocetka (funkcijom kill).

Nisam 100% siguran da je ovo resenje upotrebljivo na drugim unix-ima.

Drugo moguce resenje, bez signala i dosta jednostavnije:
Napravi jedan pipe (funkcija pipe) i u select sem listen socket-a proveravaj i njegov fd (read fd).
Kada se nesto desi sa ovim fd-om (tj. bude FD_ISSET==true) treba prekinuti select/accept petlju.
Nit koja zeli da prekine select/accept petlju treba damo da zatvori write file descriptor.
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme