2009-01-13 6 views
7

Ich habe drei Anwendungen, die über Sockets miteinander kommunizieren. Sie können alle auf ihren eigenen Maschinen leben, aber sie können sich auch eine Maschine teilen. Im Moment habe ich zwei von ihnen auf der gleichen und die dritte auf einer eigenen Maschine. Ich versuche, meine Kommunikation kugelsicher zu machen, also ziehe ich Kabel heraus und töte die Anwendungen, um sicherzustellen, dass alles wie gewünscht funktioniert.Was passiert mit Sockets, wenn ich ein Netzwerkkabel abziehe?

Hier ist eine schnelle Skizze der Sache:

alt text http://i40.tinypic.com/9vch86.png

Nun, wenn ich das Netzwerkkabel an PC2 (die rote Verbindung „Con B“), die interne Verbindung hört auf zu reden (die blaue Verbindung trennen "Con A"). Ich sende Sachen von "App 1" an den Sockel, der nie zu "App 2" gelangt.

Ich habe einen Mechanismus gemacht, der dies entdeckt und trennt und dann wieder verbindet und danach kann ich das Kabel alles abziehen, was ich will und "Con A" funktioniert einfach weiter. Es ist nur das erste Mal.

Ich habe bestätigt, Kommunikation über "Con A" vor dem Trennen von "Con B".
Ich verbinde und verbinde mich auf die gleiche Weise, es ist der gleiche Code, also gibt es keinen Unterschied.

Was passiert?

Zusätzliche Informationen durch Antworten ausgelöst: PC 1 und PC 2 teilen Adressen bis zum letzten Byte.
Ich habe einen internen Keep-Alive-Mechanismus, ich sende eine Nachricht und erwarte alle 10 Sekunden eine Antwort.
Wenn ich App 3 beende, passiert das nicht, nur wenn ich das Kabel abziehe.

Antwort

5

Welche Adresse verwenden Sie für "Con A"? Wenn Sie eine Adresse verwenden, die an den externen Netzwerkadapter gebunden ist, obwohl Sie mit demselben Computer sprechen, könnte das passieren, was Sie beschreiben.

Was Sie tun können, ist die Adresse localhost (127.0.0.1) für "Con A", die völlig unabhängig von dem sein soll, was im externen Netzwerk passiert.

5

Auf einigen Plattformen (Windows) zieht das Ziehen des Netzwerkkabels den Netzwerk-Stack an, um offene Socket-Verbindungen, die der Schnittstelle zugeordnet sind, aktiv ungültig zu machen.

In diesem Szenario ist das Ziehen eines Netzwerkkabels tatsächlich ein schlechter Test, da es Ihrer Anwendung ein positives Feedback gibt, das es in einer realen Situation möglicherweise nicht erhält.

Ein häufiger Fehler beim Schreiben von Client/Server-Anwendungen besteht darin, dass keine Anwendungsebene beibehalten oder zumindest Keepalives auf der Transportschicht aktiviert werden. Ein Anwendungs-Recv() - Daten können ansonsten für irgendeinen Fehlerzustand bis zu dem Zeitpunkt, zu dem write() s und der Schreibvorgang aufgrund des Transportschicht-Timeouts fehlschlagen, für immer blind sein.

2

Das Ziehen des Netzwerkkabels hat je nach Betriebssystem unterschiedliche Auswirkungen. Wie ein anderes Poster sagte, erkennt Windows es und macht vorhandene Verbindungen ungültig. Ihre Anwendung sollte in diesem Fall eine Meldung zum Schließen der Verbindung erhalten.

Mein Linux-Server dagegen behandelt es ziemlich anmutig. Nach einem längeren (30-40 Sekunden) Ent-verkabeln der anderen Tage war die SSH-Verbindung von meinem Laptop zum Server immer noch glücklich verfügbar und reaktionsfähig.

Solange das Kabel nicht länger als die TCP-Timeouts herausgezogen wird, sollte der Stack in der Lage sein, Pakete zu puffern und sie so schnell wie möglich erneut zu übertragen. TCP ist dafür ausgelegt. Wenn Sie TCP nicht verwenden, fallen die Pakete aus dem Ethernet-Loch und verdampfen in die Atmosphäre.

@einstein: Wenn Sie select() oder Derivate verwenden, lohnt es sich, niemals mit einem NULL-Timeout zu wählen. Immer eine vernünftige Zeitüberschreitung haben und den Socket-Status überprüfen, wenn er abläuft.

+1

Leider werden Sie dadurch nicht davor bewahrt, jemals benachrichtigt zu werden, wenn Sie nur auf Daten warten. Ohne Keepalive gibt es möglicherweise keine OOB-Benachrichtigung über Dead-Peer - der Socket-Status kann nicht dazu verwendet werden, eine Fehlerbedingung zu erkennen, ohne vorher etwas() gesendet zu haben. Deshalb sind Keepalives so wichtig. – Einstein