Toon posts:

[Linux C]TCP Socket:hoe detecteer dat comms niet mogelijk is

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een TCP-servertje geschreven dat meerdere verbindingen accepteert. Het programma gebruikt geen forks en threads, alleen select voor readfds.
Functie is om ontvangen data door te geven over een UDP verbinding en de andere kant van de UDP verbinding te laten weten welke clients er zijn.

Detecteren dat een client de verbinding verbreekt is geen probleem (socket wordt 'readable' en een leesactie op de socket geeft 0 terug). Hoe detecteer ik echter dat de netwerk kabel eruit getrokken wordt?
Als je de kabel eruit trekt gaat send nog steeds goed en een read 'event' treedt dan niet op.

Sockets zijn blocking. Moet ik non-blocking sockets gebruiken? Welke C-functie om sockets non-blocking te maken? Een paar regeltjes code worden gewaardeerd.

// Edit: Code al gevonden (fcntl); ik wist het maar kon 'm niet vinden :'(
Alleen nog even kijken of het werkt


Of is er een andere manier?

[ Voor 9% gewijzigd door Verwijderd op 09-04-2003 08:43 . Reden: Helft van oplossing gevonden ]


Verwijderd

Normaal gesproken zou je timeout() alarm() gebruiken.

-edit- domme info over timeout() -edit-

Zie man 2 alarm.
unsigned int alarm(unsigned int seconds);

DESCRIPTION
alarm arranges for a SIGALRM signal to be delivered to the
process in seconds seconds.

If seconds is zero, no new alarm is scheduled.

In any event any previously set alarm is cancelled.
Volgens mij is dit ook de "normale" manier om dit te doen. De client zal timeout'en als de kabel eruit wordt getrokken. Probleem is wel dat je in je protocol iets moet inbouwen om een connectie in stand te houden, een soort "NULL" event waarbij de client data naar de server stuurt (anders timet deze out. ;)) zonder dat deze data

[ Voor 61% gewijzigd door Verwijderd op 09-04-2003 08:48 ]


Verwijderd

Topicstarter
Bedankt, had het bericht net gewijzigd omdat de helft van de oplossing waarschijnlijk is gevonden (gebruik fcntl om te schakelen tussen blocking en non-blocking)

Ik heb geen invloed op de client en kan dus geen keep-alive messages gebruiken.

Verwijderd

Topicstarter
Ik zie nog niet hoe de alarm functie me kan helpen. Iemand die dat aan mij kan verduidelijken.

Verwijderd

Voor een timeout. Je gebruikt alarm() om de timeout lengt te zetten (bv. 10 sec), dan plaats je een signal handler naar SIGALRM (signal()) en doe je een read() of write() (blocking!). Na 10 seconden krijg je een signal als er niks ie gebeurd. Dan weet je dus dat de host offline is gegaan (of dat ie tijdelijk onbereikbaar is, maar voor een server als dit bestaat er geen verschil tussen die twee).

Verwijderd

Topicstarter
Dat heeft volgens mij dezelfde functie als 'select()'. Het nadeel van de door jou gekozen benadering lijkt me dat het programma op een socket hangt voor N seconden totdat het alarm komt. 'select()' lijkt daarvoor de betere benadering.

Verwijderd

select() wacht totdat er input is. alarm() zet daar een timeout bij. Dus eerst alarm() en dan select() geeft input als er input is met een timeout er gratis bij. ;).

Verwijderd

Topicstarter
De laatste parameter van 'select()' is ook een timeout (tot op usec nauwkeurig als het moet).
Maar goed, een oplossing komt er op deze manier niet :'(

Verwijderd

Je wilt toch dat de read() terugkomt als de kabel eruit getrokken wordt? Dat gebeurt met alarm(). Wat wil je dan?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22-08 01:56
Verwijderd schreef op 11 april 2003 @ 16:46:
Je wilt toch dat de read() terugkomt als de kabel eruit getrokken wordt? Dat gebeurt met alarm(). Wat wil je dan?
Dat gebeurt ook wel als je select een timeout meegeeft. Waarschijnlijk wil de TS checken wanneer de kabel er fysiek uitligt (uit de server zelf dus) en dat zou wel moeten kunnen (dat 'voelt' de netwerkkaart namelijk), maar of daar een mooie gestandaardiseerde manier voor bestaat, betwijfeil ik.

Als het niet om de fysieke kabel maar om de verbinding gaat, lijkt een timeout op de select call me net zo effectief als het schedulen van een alarm, wat eigenlijk hetzelfde is.

Verwijderd

Topicstarter
Waar het om gaat is dat ik moet weten wanneer de clients onbereikbaar zijn. Dit kan zijn als het netwerk op zijn gat ligt, als de kabel eruit is bij een client of bij mijn server of als de client niet aanstaat.
Ik heb twee typen clients.
Een is een terminal server waar meerdere 'terminals' aanhangen; softwarematig is iedere terminal een TCP client. Als een terminal aanstaat zal de terminal server (als client) een verbinding maken met mijn server-programma, als de terminal uitstaat zal de terminal server de verbinding met mijn programma verbreken (of niet opzetten).
Het tweede type is een client die een verbinding opzet met mijn server programma en daarna data verstuurt als data op ingangen van de client verandert (en verder niks). De verbinding kan openblijven of na een timeout door de client worden verbroken.
Beide typen worden gebruikt om signalen te monitoren.

Ik moet weten (type 1) of (als er geen verbinding wordt opgezet) de terminals niet aan staan of dat de terminal server niet aanstaat of dat de netwerk kabel er ergens uitligt. Bij het tweede type client moet ik weten of ik geen data krijg omdat er geen veranderingen aan de ingangen zijn opgetreden of omdat de box niet aanstaat of omdat de kabel er ergens uitligt.

Terwijl ik dit zit te typen, bedenk ik dat ik eigenlijk een ping functie nodig heb. Nu nog een stukje source-code daarvoor vinden.
Pagina: 1