2017-10-18 4 views
-2

Als Client mache ich eine socket(), es gibt mir eine Nummer, die ich in sktnum speichern. Ich mache dann eine connect() mit sktnum und die Remote-Adresse. Hey Presto, es ist erfolgreich, und mir wurde gesagt, dass der Kernel eine lokale IP-Adresse und Port-Nummer ausgewählt hat (damit der Server weiß, wohin er zurücksendet). Welche Funktion (Linux C/C++) rufe ich an, um herauszufinden, welchen Port und welche IP-Adresse der Kernel ausgewählt hat. (Und bitte seien Sie nicht einer dieser Leute, die sagen "Warum wollen Sie wissen")Welche Funktion sagt mir, an welche Adresse der Kernel den lokalen Socket gebunden hat?

+0

https://stackoverflow.com/questions/30597111/get-local-port-used- by-socket – melpomene

Antwort

2

Ich bin mir nicht sicher, ob ich Ihre Frage richtig verstehe. Ich verstand es die folgende Art und Weise:

Computer "A" verwendet socket() und connect() eine TCP-Verbindung zum Computer "B" zu schaffen, die unter Verwendung von socket(), bind(), listen() und access().

Die IP-Adresse und TCP-Port am Computer "B" ist bekannt (natürlich - Sie eine Verbindung zu einem bestimmten TCP-Port auf einem bestimmten Computer).

Aber wie ist es möglich, die IP-Adresse und den TCP-Port auf Computer "A" herauszufinden, die zu dieser Verbindung gehören?

Die Funktion, die das auf Computer "A" tun wird, ist getsockname().

Auf Computer "B" getpeername() wird diese Informationen zurückgeben. Wenn der Computer "B" mehrere IP-Adressen hat (z. B. mehrere Netzwerkkarten), kann der Computer "B" auch getsockname() verwenden, um seine eigene IP-Adresse zu erhalten.

Vor dem Aufruf connect() hat der Socket noch keine Portnummer und keine IP-Adresse. So ruft getsockname() vor dem Aufruf connect() keinen Sinn.

Der Grund dafür ist einfach: Wenn ein Computer mehrere Netzwerkkarten mit unterschiedlichen IP-Adressen hat, kann die IP-Adresse auf der Seite des Computers "A" nicht bekannt sein, bevor bekannt ist, welche der Netzwerkkarten verwendet werden muss. (Beachten Sie, dass localhost gesehen wird als separate "Netzwerkkarte" mit der IP-Adresse 127.0.0.1 durch das O!)

EDIT

Aber ich glaube, Sie könnten nur erhalten ... 192.168. ... Es gibt Ihnen nicht die ... IP-Adresse, die Sie im Internet zugewiesen haben. Ihr Problem kann auf folgende Weise erklärt werden:

Die ursprüngliche Idee des Internets war, dass jeder Computer seine eigene globale IP-Adresse hat (das ist, was Sie rufen: „Adressen, die Sie im Internet zugeordnet sind“).

Diese Idee hat sich nie geändert: Fast jede PC-Software (einschließlich Betriebssystem) ist für Computer mit einer globalen IP-Adresse geschrieben.

Da Ihr Provider Ihnen nur eine IP-Adresse geben kann, "täuscht" Ihr Router Ihre Computer, indem er ein Internet "simuliert", in dem die lokalen Computer globale Adressen haben (z. B. im Bereich 192.168.).

Aufgrund dieser "Simulation" kann sich der Computer genauso verhalten wie 192.168.x.y ist seine globale IP-Adresse im Internet. Der Computer hat nicht einmal Informationen darüber, dass dies keine globale IP-Adresse ist!

So ist es klar, dass diese Funktionen 192.168.x.y zurückgeben, weil das Betriebssystem "denkt", dass dies die globale Adresse im Internet ist!

Das einzige Gerät, das Informationen über die reale globale Adresse (und über den echten TCP-Port !!!) hat, ist der Router!

Viele Anbieter verwenden CGNAT, was bedeutet, dass sogar mehrere Internetverbindungen eine IP-Adresse teilen. In diesem Fall ist das einzige Gerät mit diesen Informationen der Router des Anbieters.

Wenn Sie die echte IP-Adresse und den echten TCP-Port (wie aus dem Internet gesehen) benötigen, erhalten Sie diese Informationen vom Router. Abhängig vom Router-Modell wird es nicht möglich sein, Informationen über die tatsächlichen Adressen zu erhalten.

Ich bezweifle, dass es einen Router auf dem Markt gibt, mit dem Sie den echten TCP-Port auslesen können.

Dies war ein Grund, warum IPv6 entwickelt: Mit IPv6 jedem Computer wieder seine eigene IP-Adresse haben kann ...

+0

Martin - Ich glaube nicht, dass Sie Recht haben. getsockname() benötigt vom Aufrufer einen Socket-Dateideskriptor (sockfd). Aber wir würden den Einheimischen nicht kennen. Wir kennen das, was wir mit socket() erstellt haben, aber als wir es mit connect() benutzt haben, wurde es mit der REMOTE-IP-Adresse verknüpft, nicht mit der lokalen. – Clive

+0

Ich denke, ich habe vielleicht eine Antwort ausgearbeitet, aber es reicht immer noch nicht für das, was ich will. Sie könnten gethostname() verwenden und dann getaddrinfo(), was es zurückgibt. Aber ich denke, dass Sie nur 127.0.0.1 oder eine Adresse 192.168 erhalten. usw., was das Gateway (Router) Ihnen möglicherweise in einem DHCP-Vorgang zugeteilt hat. Es gibt Ihnen nicht die (temporäre) IP-Adresse, die Sie im Internet zugewiesen haben. – Clive

+0

@Clive Bitte sehe meine Bearbeitung: Sorry, aber ich denke was du machen willst ist nicht möglich. –

Verwandte Themen