Socket-Server (in c++) , Client als Java-Applet
-
Hallo,
ich möchte auf einer Web-Site ne Applet schreiben, die Daten für die Darstellung auf der Site von entferntem Server abholt.
Wozu das Ganze? Die Messdaten eines Systems werden von einer (in c++) geschriebenen Anwendung erfasst. Meine Idee war es, für die Daten einen Socket-Server zu schreiben, der die Daten bereitstellt.Ich habe zwei kleine Progis (ab)geschreiben, die soweit funzen.
Server in c++, Client in Java. Die Anfrage vom Client akzeptiert der Server, nur Daten senden und empfangen klappt nicht. Kann mir jemand sagen, ob das überhaupt möglich ist, kompatibil usw.? Oder vielleicht schon jemad gemacht ?Danke im voraus
Roman
-
Bisschen mehr musst du schon verraten.
-
Ja das ist kompatibel na klar aber warum es nicht geht kann ich nicht sagen, dafür ist deine Info zu vage!
-
afaik: aus sicherheitsgründen kann ein applet nur die ip des servers ansprechen, von dem es geladen wurde, "fremde IPs" kann man nicht ansprechen. ist so wie es mit den cookies sein sollte. vielleicht kannst du das in den sicherheitseinstellungen ändern, oder du bietest ein normales javaprogramm zum download an und das kann sich zu jedem server verbinden.
rapso->greets();
-
Danke Leute, ich habe es gerade mal geschafft, einen c++ Echo Server (ab)zu schreiben, der auf die Java- Client Anforderung richtig antwortet.
Beide sind Konsolenproggis.
Server bekommt PortNr. und Client ServerName und PortNr. als Startparameter.
Das zweite Zeichen von der Nachricht wird in ein "+" umgewandelt, damit ich sehen kann, ob die Nachricht tatsächlich vom Server verarbeitet wurde.
Es ist recht einfach geschrieben, ohne Fehlerkorr. u.s.w. , ich wollte die Funktionen selbst testen.
Hier der Code:[code] // socket_server3.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung. // #include "stdafx.h" #include "socket_server3.h" #include <iostream> // For cout, cerr #include <afxsock.h> // For CSocket #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif using namespace std; const int MAXPENDING = 5; // Maximum outstanding connection requests const int RECVBUFSIZE = 256; void DieWithError(char* errorMessage); // Error handling function void HandleTCPClient(CSocket& clntSock); // TCP client handling function int main(int argc, char* argv[]) { // Initialize MFC and print an error on failure if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { DieWithError("Fatal Error: MFC initialization failed"); } // Initialize the AfxSocket AfxSocketInit(NULL); if (argc != 2) { // Test for correct number of arguments cerr << "Usage: " << argv[0] << " <Server Port>" << endl; exit(1); } int echoServPort = atoi(argv[1]); // First arg: local port CSocket servSock; // Socket descriptor for server // Create the server socket if (!servSock.Create(echoServPort)) { DieWithError("servSock.Create() failed"); } // Mark the socket so it will listen for incoming connections if (!servSock.Listen(MAXPENDING)) { DieWithError("servSock.Listen() failed"); } for(;;) { // Run forever SOCKADDR_IN echoClntAddr; // Client address // Get the size of the in-out parameter int clntLen = sizeof(echoClntAddr); CSocket clntSock; // Socket descriptor for client // Wait for a client to connect if (!servSock.Accept(clntSock)) { DieWithError("servSock.Accept() failed"); } // ClntSock is connected to a client! // Get the client's host name if (!clntSock.GetPeerName((SOCKADDR*)&echoClntAddr, &clntLen)) { DieWithError("clntSock.GetPeerName() failed"); } cout << "Handling client " << inet_ntoa(echoClntAddr.sin_addr) << endl; HandleTCPClient(clntSock); } // NOT REACHED return 0; } ////////////////////////////////////////////////////////////////////////////////////// void HandleTCPClient(CSocket& clntSock) { char echoBuffer[RECVBUFSIZE]; // Buffer for echo string int recvMsgSize; // Size of received message // Recieve message from client recvMsgSize = clntSock.Receive(echoBuffer, RECVBUFSIZE, 0); if (recvMsgSize < 0) { DieWithError("clntSock.Receive() failed"); } // Send received string and receive again until end of transmission while (recvMsgSize > 0) { // Echo message back to client echoBuffer[1] = '+'; if (clntSock.Send(echoBuffer, recvMsgSize, 0) != recvMsgSize) { DieWithError("clntSock.Send() sent a different number of bytes than received"); } // See if there is more data to receive recvMsgSize = clntSock.Receive(echoBuffer, RECVBUFSIZE, 0); if (recvMsgSize < 0) { DieWithError("clntSock.Receive() more failed"); } } clntSock.Close(); // Close client socket } ///////////////////////////////////////////////////////////////////////////////////////// void DieWithError(char* errorMessage) { cerr << strerror(errno) << ": " << errorMessage << endl; exit(0); } [/code]
Client :
[code] /* Sockets- Client */ /* Parameter: - Rechnername des Servers */ /* - Portnummer des Serverprozesses */ import java.io.*; import java.net.*; public class EchoKlient { public static void main(String[] args) { try { Socket socket = new Socket(args[0], Integer.parseInt(args[1])); OutputStream os = socket.getOutputStream(); DataInputStream is = new DataInputStream(socket.getInputStream()); int c; String echo; while ((c = System.in.read()) != -1) { os.write((byte)c); if (c == '\n') { os.flush(); echo = is.readLine(); System.out.println(echo); } } os.close(); is.close(); socket.close(); } catch (Exception e) { System.err.println("Ausnahmebedingung, vermutlich Terminierung der Servers"); } } }
[/code]
Hej, wenn es so funzt, dann stehen alle Türen offen, man kann die Daten austauschen, wie man will, vorrausgesetzt sie werden in Byte-Streams übertragen.
Sowas, wie (in java) Objekte verschicken wird wohl nicht möglich sein, oder doch?
Muss wohl etwas experimentieren.
Für jeden Link,Tipp oder Erfahrungsberichte zu diesen Thema ,würde ich mich sehr freuen.Roman
-
rapso schrieb:
afaik: aus sicherheitsgründen kann ein applet nur die ip des servers ansprechen, von dem es geladen wurde, "fremde IPs" kann man nicht ansprechen. ist so wie es mit den cookies sein sollte. vielleicht kannst du das in den sicherheitseinstellungen ändern, oder du bietest ein normales javaprogramm zum download an und das kann sich zu jedem server verbinden.
Das gilt nur für unsignierte Applets. Wenn man das mit einer Signatur versieht, dann kann man letztendlich alles mit Applets machen, was man will. Der Nutzer kriegt dann allerdings eine entsprechende Warnung vor dem Start des Applets. Da muss er dann erst bestätigen, dass er das dem Applet erlaubt.
-
Roman007 schrieb:
Sowas, wie (in java) Objekte verschicken wird wohl nicht möglich sein, oder doch?
Muss wohl etwas experimentieren.Natürlich geht das. ...so lange es sich um Objekte handelt, deren Klassen das Serializable Interface implementieren. ...oder habe ich jetzt etwas falsch verstanden.
Über RMI gibt es sogar die Möglichkeit, Objekte von entfernten Rechnern aus zu nutzen. Da kann man auf dem entfernten Rechner einen Methodenaufruf machen, der dann auf deinem Rechner ausgeführt wird, oder wo immer sich das Objekt befindet.
-
Du kannst mit Java serialisierte Objekte nicht einfach so in C++ wieder zusammensetzen.
Soweit ich weiß sind die mit Java serialisierten Objekte ja mit XML formatiert, du könntest aus diesen Daten, dann in C++ wieder ein Objekt erstellen, dass dem versendeten entspricht. Dürft aber etwas aufwändiger werden, da du ja für jede Java Klasse ne C++ Klasse schreiben müsstest.Kenn mich mit RPC und was es da alles in diese Richtung gibt nicht gut aus, aber ich meine es gibt da so nen Standard-Protokoll/System mit dem das möglich wäre.
Mir fällt da jetzt nur nicht mehr der Namen ein, daher bin ich mir auch nicht sicher ob ich da jetzt nicht etwas verwechsle.
-
@Rapso
Die Web-Seite wird vom gleichen Server geladen, wo auch mein cpp-Socketserver laufen wird, also ist es richtig, dass der Applet die Verbindung mit dem Server, von dem er aufgerufen worden ist, aufnehmen soll
Mehr brauche ich nicht.
@Gregor@Home
Das es mit java geht ist klar, aber ob es das Gegenstück in c++ gibts?
Oder muss man aus dem Datenstrom den Aufbau des Objektes erst mal parsen?
Wie gesagt, ich muss etwas experimentierenRoman
-
Habe eben etwas nachgeforscht und der Standard den ich meinte nennt sich SOAP.
-
Gregor@Home schrieb:
Das gilt nur für unsignierte Applets. Wenn man das mit einer Signatur versieht, dann kann man letztendlich alles mit Applets machen, was man will. Der Nutzer kriegt dann allerdings eine entsprechende Warnung vor dem Start des Applets. Da muss er dann erst bestätigen, dass er das dem Applet erlaubt.
wust ich nicht so genau... wo signiert man die denn? bei sun direkt?
rapso->greets();
-
Sun Direkt ist ne Autoversicherung.
-
Du willst uns doch nicht erzählen das du jetzt arbeitest.
-
rapso schrieb:
Gregor@Home schrieb:
Das gilt nur für unsignierte Applets. Wenn man das mit einer Signatur versieht, dann kann man letztendlich alles mit Applets machen, was man will. Der Nutzer kriegt dann allerdings eine entsprechende Warnung vor dem Start des Applets. Da muss er dann erst bestätigen, dass er das dem Applet erlaubt.
wust ich nicht so genau... wo signiert man die denn? bei sun direkt?
rapso->greets();
Die kannst du bei dir zuhause signieren. Siehe hier, das Tool "Jarsigner" (und auch das "keytool"). Allerdings wird auf dem Dialog für den Benutzer stehen, dass du nicht vertrauenswürdig bist
(im Endeffekt ist das aber egal).
-
LOL..... schrieb:
Du willst uns doch nicht erzählen das du jetzt arbeitest.
Crunchtime halt. :xmas1: