Forum: PC-Programmierung Client/Server verbindung überprüfen


von Carolin Z. (seobalis)


Lesenswert?

Hallo Leute,

wie kann ich festlegen, ob die Verbindung zwischen Client und Server 
noch existiert, wenn ich gerade in einem Schleifer bin
wie z.B:
1
server_sock = socket(AF_INET, SOCK_STREAM, 0);
2
    
3
opt = 1;
4
setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
5
6
7
server.sin_family = AF_INET;
8
server.sin_port = htons(src_port);
9
server.sin_addr.s_addr = inet_addr(src_addr);
10
11
bind(server_sock, (struct sockaddr*) &server, sizeof(server));
12
13
listen(server_sock, 5);
14
15
len = (int) sizeof(client);
16
accept_sock = accept(server_sock, (struct sockaddr*) &client, &len);
17
18
recv_len = recv(accept_sock, buf, 1024, 0); 
19
20
for(;;) {
21
// do something
22
// wie kann ich die Verbindung überprüfen ohne recv funktion zu rufen
23
// hier soll der Schleifer abgebrochen werden, wenn die Verbindung nicht mehr existiert
24
25
}

Es wäre sehr nett wenn ihr mir weiter helfen könntet.

Grüße,

Carolin

von Karl H. (kbuchegg)


Lesenswert?

Carolin Zapa schrieb:

> Es wäre sehr nett wenn ihr mir weiter helfen könntet.

Üblicherweise definiert man einen 'Is Alive' bzw 'Keep Alive' 
Mechanismus. Der könnte zb so aussehen.
Jeder Kommunikationspartner hat einen Timer mitlaufen. Jedesmal, wenn 
der Empfänger (egal ob Client oder Server) etwas empfängt, setzt er den 
Timer zurück. Läuft der Timer ab, dann wird die Verbindung per 
Definition als unterbrochen definiert.
Damit jetzt aber die Verbindung nicht als unterbrochen gilt, nur weil 
keiner etwas zu sagen hat, gibt es eine 'Keep Alive' Nachricht. Ihre 
einzige Aufgabe ist es, der Gegenstelle mitzuteilen "Juhu, ich bin noch 
da". Bleibt also die Keep Alive Meldung eine bestimmte Zeitspanne aus 
und gibt es auch sonst nicht zu übertragen was den Timer zurücksetzen 
würde, dann geht die Gegenstelle davon aus, dass die Verbindung 
abgebrochen ist.

von Carolin Z. (seobalis)


Lesenswert?

danke schon mal für deine Antwort. Mit setsockopt(SO_KEEPALIVE) kann man 
"keep alive" für socket einstellen, aber ich weiß immer noch nicht wie 
ich in meinem Fall anwenden soll, damit ich weiß dass mein Partner nicht 
mehr da ist ohne recv funktion zu benutzen. Mit getsockopt() kann ich 
nur wissen ob Keep alive eingeschaltet wird. Mit welcher Funktion oder 
Anwendung soll ich im for(;;) Schleifer rufen

von Karl H. (kbuchegg)


Lesenswert?

Carolin Zapa schrieb:
> danke schon mal für deine Antwort. Mit setsockopt(SO_KEEPALIVE) kann man
> "keep alive" für socket einstellen,

Das kann die Lösung sein, kann es aber auch nicht sein.

Hast du danach schon einmal gegoogelt?
Von "Der Keep Alive wird alle 2 Stunden ausgelöst und kann nur sehr 
umständlich konfiguriert werden" bis hin zu "Nicht alle Netzwerk Typen 
unterstützen von sich aus ein Keep Alive" findet sich da alles mögliche.

> ich in meinem Fall anwenden soll,

implementiere es dir selber!

von Volker Z. (vza)


Lesenswert?

1
 recv_len = recv(accept_sock, buf, 1024, 0);
2
3
 if(recv_len == SOCKET_ERROR)
4
 {
5
    err = WSAGetLastError();
6
    switch(err)
7
    {
8
    case WSAECONNRESET :
9
      printf("socket  reset.\n");
10
      break;
11
    default :
12
      serror("recv",err);
13
    }
14
 }
15
 else
16
 {
17
    if(0 == recv_len)
18
    {
19
       printf("socket closed from remote.\n");
20
    }
21
    else
22
    {
23
       // Hier empfang auswerten
24
    }
25
 }

Bis Conection_Reset kommt kann es typ. 2min dauern.

von Carolin Z. (seobalis)


Lesenswert?

>     if(0 == recv_len)
>     {
>        printf("socket closed from remote.\n");
>     }
>     else
>     {
>        // Hier empfang auswerten
>     }

Wenn ich auf Recv funk zugreifen kann, dann weiß ich ob mein Partner 
noch da ist, aber ich bin gerade in For(;;) schleife, und kann oder darf 
die recv funktion nicht rufen. Von daher suche ich eine andere 
Möglichkeit zu wissen ob die Verbindung noch lebt ohne recv zu rufen

von Karl H. (kbuchegg)


Lesenswert?

Dein Problem ist äquivlant zu:

Dein Kumpel fährt in den Amazonas auf Expedition.
Wenn er sich nicht regelmässig bei dir meldet und du ihn nicht anrufen 
darfst, hast du keine Möglichkeit zu wissen, ob er noch am Leben ist 
oder ob es besser wäre, eine Rettungsexpedition loszuschicken.

Was ist daran so schwer zu verstehen?

Genau das musst du implementieren: Die Gegenstelle meldet sich in 
regelmässigen Abständen um mitzuteilen: Es geht mir gut.

Zwischen diesen zeitlichen "Checkpoints" hängt der Status in der Luft, 
erst wenn die Meldung zum verabredeten Zeitpunkt nicht eintrifft, weißt 
du das etwas passiert sein muss.

Und nein. Ohne einen recv oder einen select ist das nicht zu machen.
Du darfst den Socket nicht im 'Blocking Mode betreiben', so dass recv 
nicht aktiv auf Daten wartet, sondern auch dann zurückkommt, wenn keine 
Daten vorhanden sind.

http://www.scottklement.com/rpg/socktut/nonblocking.html

von Klaus W. (mfgkw)


Lesenswert?

Ja, entweder non blocking (meist ungeschickt) oder select() (meist
geschickter, aber komischerweise drücken sich die Leute davor).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.