Gewünschte Adresse kann nicht zugeordnet werden – mögliche Ursachen?

Lesezeit: 4 Minuten

Benutzer-Avatar
dbeer

Ich habe ein Programm, das aus einem Master-Server und verteilten Slave-Servern besteht. Die Slave-Server senden Statusaktualisierungen an den Server, und wenn der Server in einem festgelegten Zeitraum nichts von einem bestimmten Slave gehört hat, markiert er den Slave als ausgefallen. Dies geschieht konsequent.

Beim Überprüfen von Protokollen habe ich festgestellt, dass der Slave nur eine Statusaktualisierung an den Server senden kann und dann nie eine weitere Aktualisierung senden kann, wobei der Aufruf von connect() immer fehlschlägt. “Kann die angeforderte Adresse nicht zuweisen (99).

Seltsamerweise kann der Slave mehrere andere Aktualisierungen an den Server senden, und alle Verbindungen erfolgen über denselben Port. Es scheint, dass die häufigste Ursache für diesen Fehler darin besteht, dass Verbindungen offen gelassen werden, aber ich habe Probleme, etwas zu finden, das offen gelassen wurde. Gibt es andere mögliche Erklärungen?

Zur Verdeutlichung, hier ist, wie ich mich verbinde:

struct sockaddr *sa; // parameter
size_t           sa_size; //parameter
int              i = 1;
int              stream;

stream = socket(AF_INET,SOCK_STREAM,0);
setsockopt(stream,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));
bindresvport(stream,NULL);
connect(stream,sa,sa_size);

Dieser Code dient dazu, eine Verbindung zu einem anderen Server herzustellen, und ein Fehler bei einem dieser 4 Aufrufe führt dazu, dass die Funktion fehlschlägt.

  • Ich habe überprüft, ob sowohl der Port als auch die IP-Adresse korrekt sind.

    – dbeer

    3. Oktober 2011 um 21:21 Uhr

Benutzer-Avatar
dbeer

Es stellt sich heraus, dass das Problem wirklich darin bestand, dass die Adresse besetzt war – die Besetztheit wurde durch einige andere Probleme bei der Handhabung der Netzwerkkommunikation verursacht. Ihre Beiträge haben mir geholfen, dies herauszufinden. Vielen Dank.

BEARBEITEN: Genauer gesagt bestanden die Probleme bei der Handhabung unserer Netzwerkkommunikation darin, dass diese Statusaktualisierungen ständig erneut gesendet wurden, wenn die erste fehlschlug. Es war nur eine Frage der Zeit, bis jeder verteilte Slave gleichzeitig versuchte, sein Status-Update zu senden, was unser Netzwerk überlastete.

  • Ich würde gerne eine Erläuterung zu „busy“ geben, falls dies die Ursache für denselben Fehler hier drüben in meinem eigenen Code ist – meinst du „der Server, der Verbindungen akzeptiert, hatte eine zu lange Warteschlange von Sockets, die auf accept() für eine andere Verbindung warten in die Warteschlange dürfen?“ Oder ein anderer Umstand? Vielen Dank!

    – Brandon Rhodes

    7. März 2013 um 13:32 Uhr

  • @BrandonRhodes Unser Problem war, dass wir einige Wiederholungsversuche ohne einen geeigneten Backoff-Algorithmus hatten, sodass wir jede Sekunde Hunderte oder mehr Verbindungsversuche mit demselben Socket hatten. Dieser Streit verursachte unser Scheitern. Die Implementierung eines geeigneten Backoff-Algorithmus war entscheidend, um dieses Problem zu lösen.

    – dbeer

    7. März 2013 um 16:26 Uhr

Vielleicht hilft hier SO_REUSEADDR?
http://www.unixguide.net/network/socketfaq/4.5.shtml

  • SO_REUSEADDR wird für alle Verbindungen gesetzt.

    – dbeer

    3. Oktober 2011 um 21:23 Uhr

  • hier ist ein ähnliches: stackoverflow.com/questions/3886506/…

    – dmh2000

    3. Oktober 2011 um 22:35 Uhr

  • @dmh2000 – Ich habe mir dieses Beispiel vor dem Posten angesehen und hatte keinen Erfolg beim Versuch, diese Faktoren zu untersuchen. Ich frage mich, ob ich einfach weiter suchen muss oder ob es etwas gibt, das ich nicht berücksichtige.

    – dbeer

    4. Oktober 2011 um 17:10 Uhr

  • Wird diese Funktion, von der Sie sprechen, mehrmals ausgeführt? Schließen Sie den Socket, bevor Sie connect erneut aufrufen? Können Sie in Ihrer Frage den Unterschied zwischen “Statusaktualisierungen” und “anderen Aktualisierungen” erläutern? Ich bin verwirrt, warum Sie sagen “… Slave kann nur eine Statusaktualisierung senden …” und dann “… Slave kann mehrere andere Updates senden …”.

    – Michel

    4. Oktober 2011 um 18:31 Uhr

  • @Michel – die Verbindung wird sofort geschlossen, nachdem das Update gesendet und die Bestätigung erhalten wurde, dass es empfangen wurde. Die „anderen Aktualisierungen“ berichten hauptsächlich über Aufgaben, die der Server dem Slave aufgetragen hat. Der Slave kann den Server für diese Art von Berichten kontaktieren, aber nicht für seine Statusaktualisierung. Es ist verwirrend. Die anderen Updates schreiben meistens auf einen vom Master-Server geöffneten Socket zurück, und für diese Updates öffnet der Slave die Verbindung.

    – dbeer

    4. Oktober 2011 um 20:48 Uhr

Dies ist nur ein Schuss ins Blaue: Wenn Sie zuerst connect ohne Bindung aufrufen, weist das System Ihren lokalen Port zu, und wenn Sie mehrere Threads haben, die sich verbinden und trennen, könnte es möglicherweise versuchen, einen bereits verwendeten Port zuzuweisen. die Kernel-Quelldatei inet_connection_sock.c weist auf diesen Zustand hin. Versuchen Sie einfach als Experiment, zuerst eine Bindung an einen lokalen Port durchzuführen, und stellen Sie sicher, dass jede Bindung/Verbindung eine andere lokale Portnummer verwendet.

  • Entschuldigung, ich habe nicht auf meinen Code geschaut, als ich das gepostet habe. Ich rufe eine Bindung auf, bevor ich mich verbinde. Ich werde meine Frage aktualisieren, um besser zu zeigen, was ich tue.

    – dbeer

    4. Oktober 2011 um 17:12 Uhr

Okay, mein Problem war nicht der Port, sondern die Bindungsadresse. Mein Server hat eine interne Adresse (10.0.0.4) und eine externe Adresse (52.175.223.XX). Als ich versuchte, eine Verbindung herzustellen mit:

$sock = @stream_socket_server('tcp://52.175.223.XX:123', $errNo, $errStr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN);

Es schlug fehl, weil der lokale Socket 10.0.0.4 war und nicht der externe 52.175.223.XX. Sie können die lokal verfügbaren Schnittstellen mit auschecken sudo ifconfig.

sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.ipv4.tcp_tw_recycle=1

  • Ohne Erklärung hat diese Antwort keinen Wert.

    – Pavel Simerda

    17. Juni 2016 um 12:09 Uhr


  • Ohne Erklärung hat diese Antwort keinen Wert.

    – Pavel Simerda

    17. Juni 2016 um 12:09 Uhr


1382070cookie-checkGewünschte Adresse kann nicht zugeordnet werden – mögliche Ursachen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy