Ich habe ein Linux-Programm, das in zwei Teile aufgeteilt ist.
Ein Teil durchläuft NAT, um entweder einen UDP-Sockel (UDP-Lochung) oder einen TCP-Sockel (TCP-Lochung) zu erhalten. Teil eins ist in C geschrieben, um native Funktionen zu ermöglichen, die den NAT-Traversal-Prozess erleichtern oder verbessern. Teil zwei verwendet tatsächlich den verbundenen Socket, der über die im ersten Teil durchgeführte NAT-Traversierung erhalten wurde.
Jetzt ist hier das Problem. Ich möchte, dass der erste Teil, der Teil, der den Sockel erhält, unabhängig vom zweiten Teil ist, der Teil, der den Sockel für einen anwendungsspezifischen Zweck verwendet. Zum Beispiel möchte ich, dass der erste Teil für eine Vielzahl verschiedener Anwendungen wiederverwendbar ist, die alle UDP- und TCP-Verbindungen benötigen, die zwischen Peers eingerichtet wurden.
Im Moment möchte ich, dass der zweite Teil (der Anwendungsteil) in Java und nicht in C oder C ++ geschrieben wird. Ich möchte, dass der zweite Teil eine Socket-Verbindung verwendet, die von dem für NAT-Traversal zuständigen C-Code erhalten wurde. Nehmen wir an, der erste Teil stellt eine Verbindung her und gibt dann eine Struktur zurück:
%Vor%Der C-Code im ersten Teil kann diese POD / struct für den Java-Code im zweiten Teil entweder über JNI (Java Native Interface) oder über Interprozeß-Kommunikation bereitstellen.
Ich möchte, dass der Java-Code diese Informationen verwendet, um ein Objekt zu erstellen, dessen deklarierter Typ entweder java.net.DatagramSocket oder java.net.Socket ist und das Objekt dann verwendet, wenn ein DatagramSocket oder Socket erwartet wird.
Als Ausgangspunkt betrachten Sie den folgenden Beispielcode ...
%Vor%Der Code lässt den Eindruck entstehen, dass es möglich ist, einen gebundenen {@link ServerSocket} für den angegebenen Dateideskriptor neu zu erstellen. " Bedeutet dies, dass es auch möglich ist, einen gebundenen {@link java.net.Socket} auf dem gegebenen Dateideskriptor wieder herzustellen? Was ist mit einem gebundenen {@link java.net.DatagramSocket}?
%Vor%Sie können den Dateideskriptor zwischen Prozessen (zumindest auf POSIX-Systemen) übertragen, indem Sie Kann ich einen Dateideskriptor für einen anderen Prozess unter Linux freigeben oder sind sie lokal für den Prozess?
Auch wie in Kommentaren erwähnt (Danke an @Andrew Henle) können Sie Java durch Reflexion hacken und IO-Streams für bestehende Dateideskriptoren erstellen: Kann ich einen Java-Socket von einer Datei-Deskriptor-Nummer bekommen? Es ist auch möglich, die Socket-Klasse zu erweitern und die Methoden getInputStream / getOutputStream zu überschreiben.
Aber eigentlich schlage ich vor, dass Sie den ersten Teil als Proxy verwenden. Der Java-Teil öffnet einfach den Server-Socket auf localhost und dann überträgt C ++ - Teil den Datenverkehr zwischen localhost und der WAN-Adresse erneut.
Sie stellen zwei verschiedene Fragen. Können Sie einen gebundenen Socket aus C-Code übergeben, der in einem separaten Prozess geschrieben wurde, und können Sie einen gebundenen Socket aus C-Code übergeben, der in demselben Prozess geschrieben wurde.
Für den ersten Teil, nein, ist es nicht möglich, wenn der C-Code in einer Anwendung ist und der Java-Code ein anderer ist, denn wenn es möglich wäre, könnten mehrere verschiedene Anwendungen einen Socket passieren (ohne SCM_RIGHTS). Das Beenden der Anwendung, die den Socket ursprünglich erstellt und gebunden hat, würde Probleme für die anderen Anwendungen verursachen, die diesen Socket verwenden / teilen.
Da sich der C-Code im nativen Teil einer Java-Anwendung befindet (dh über jni), könnte das Betriebssystem in diesem Fall nicht unterscheiden, ob der Socket im Java-Teil des Benutzercodes oder ist der C-Teil, so dass Sie nicht auf das Problem stoßen, das im vorherigen Absatz eingeführt wurde. Es ist möglich, einen Socket (Dateideskriptor int und nativen Socketdeskriptor) zwischen Java und nativem Code zu übergeben (siehe link ), aber das sagt Ihnen nicht, ob es in diesem Szenario praktisch wäre.
Was das Erstellen eines java.net.Socket oder eines java.net.DatagramSocket aus einem gebundenen Socket-Dateideskriptor betrifft, der vom jni-Code kam, habe ich keine Ahnung. Sie müssten es selbst ausprobieren.