Avatar billede ezrider Nybegynder
06. september 2002 - 12:41 Der er 14 kommentarer og
2 løsninger

socket timeout

Jeg er ved at lave et program til "alive check" mellem 2 maskiner (server/client) på linux i c++ - dette gøres vha. sockets.

Hvordan sættes en timeout for en socket-forbindelse, således at forbindelsen lukkes ned efter eksempelvis 200 ms?

Dette skal bruges, hvis serveren ikke svarer på klientens forespørgsel.
Avatar billede jpk Nybegynder
06. september 2002 - 14:57 #1
Jeg ved ikke om man kan sætte en timeout på, men ellers kan du starte en ny tråd, lade den prøve at connecte og checke fra din hovedtråd, om det lykkedes...
Avatar billede soepro Nybegynder
09. september 2002 - 09:20 #2
og så lave "kill" af tråden hvis den ikke bliver færdig inden for den ønskede timeout grænse.

TClientSocket og TServerSocket componenterne i BCB *har* en timeout property, men om de har implementeret det vha. tråden, eller der findes en i de alm. socket API'er ved jeg ikke.
Avatar billede stringbuffer Nybegynder
09. september 2002 - 15:19 #3
brug select()
Du sætter din socket i non-blocking mode (f.eks. med ioctl()) og så åbner din forbindelse. Så kalder du select med en timeval på det ønskede antal ms og tjekker for skrivbarhed eller læsbarhed af din socket, afhængigt af om du skal sende noget til din server først eller omvendt. Hvis select giver 0, er der opstået timeout og du kan derfor kalde close() på din socket.
Avatar billede soepro Nybegynder
10. september 2002 - 08:24 #4
stringbuffer >> Nå på den lumske (dog simple) måde !
Avatar billede stringbuffer Nybegynder
10. september 2002 - 13:31 #5
// er da ikke lumsk *G*
Avatar billede tuxic Nybegynder
15. september 2002 - 01:24 #6
En anden ide er bruge TCP's indbyggede keep-alive på socket. Det kan sættes når socket'en oprettes.
Avatar billede soepro Nybegynder
16. september 2002 - 08:12 #7
tuxic >> "Dør" socket'en så efter n sekunder (sat som keep-alive), hvis den ikke har fået noget svar ?
Avatar billede stringbuffer Nybegynder
16. september 2002 - 10:28 #8
Det svarer til at den anden side lukker forbindelsen. Husk at SO_KEEPALIVE bruger en default timeout før en keepalive-probe sendes på MINDST 2 timer. Jeg ved ikke hvordan man kan stille på dette interval, måske kan man gøre det med sysctl, så bliver det bare for alle forbindelser.... hvis det er BSD-lignende OS, er der måske en kerneparameter, der hedder tcp_keepidle eller sårn..

ezrider <- Jeg har vist misforstået spørgsmålet, troede at det var timeout på connect(), du ville lave, men det er åbenbart mere tjekke status for en åben forbindelse.

En løsning kan være at sende f.eks. tomme requests (linieskift-tegn eller lign.) til din server med nogle minutters mellemrum eller hvad det nu skal være. Hvis forbindelsen er blevet brudt får du en SIGPIPE, som du så kan handle.
Avatar billede soepro Nybegynder
16. september 2002 - 13:42 #9
stringbuffer >> Dermed har du dine keepalive meddelelser og inddirekte derved også timeout.
Avatar billede stringbuffer Nybegynder
16. september 2002 - 14:19 #10
Hvis det dog kun er til at se om maskinen er i live, ville det da ikke være bedre bare at pinge den?
Avatar billede soepro Nybegynder
16. september 2002 - 14:45 #11
Problemet er vel at programmet skal forsøge connect til serveren i et (kortere) stykke tid - derefter opgive. Her kunnet ping vel være en udemærket løsning, hvis man kan checke resultatet af den - så kan man det ? (Og er det så ikke svaret på dette spørgsmål.)
Avatar billede stringbuffer Nybegynder
16. september 2002 - 19:53 #12
Selvfølgelig kan man det, her er et eksempel på et lille "ping" program, fandt den via google: http://www.linuxsocket.org/books/Sockets/programs/part4/chap18/myping.c
Avatar billede tuxic Nybegynder
16. september 2002 - 20:05 #13
Ifølge:
http://www.remote.org/jochen/mail/popular/doc/html/tcp-keepalive.htm
kan man på Linux-systemer sætte Keep-Alive timeout'en i:
/proc/sys/net/ipv4/tcp_keepalive_time
Det er så en system wide setting. Ifølge TCP-specificationen kan man sætte tcp på socket niveau (og det kan man oxo i .NET fx). I windows kan man oxo sætte det på NIC-niveau.
Det er korrekt at default er 2 timer, men det kan man jo bare stille på.
Bemærk, at det er overlegent i forhold til ping. ping fejler jo hvis maskinen er død, men ikke hvis det bare er den anden af socket'en der er død.
200 ms forekommer desuden at være kort tid, men ok det er jo bare min (forblommede?) ide.
HTH
Avatar billede tuxic Nybegynder
16. september 2002 - 20:06 #14
ok, jeg er vist lidt kortfattet:
Bemærk, at keep-alive er overlegent i forhold til ping. ping fejler jo hvis maskinen er død, men ikke hvis det bare er den anden ende af socket'en der er død.
Avatar billede stringbuffer Nybegynder
16. september 2002 - 22:09 #15
Når man ikke får en ICMP echo reply så ved man da at maskinen er død?
Og ja, 200 ms er nok ALT for kort tid... selv med keepalive skaber det nok en vis belastning af de to maskiners protokolstakke.
Avatar billede tuxic Nybegynder
16. september 2002 - 22:17 #16
>Når man ikke får en ICMP echo reply så ved man da at maskinen er >død?
Præcis. Det er derfor at det er bedre at bruge keep-alive. Det kan jo tænkes at server programmet er gået ned, men at maskinen stadig svarer på ping requests.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester