Entwickler-Ecke
Internet / Netzwerk - Delphi Socket-Server mit WINE unter Linux
cyberbug - So 01.11.09 22:17
Titel: Delphi Socket-Server mit WINE unter Linux
Hallöchen alle miteinander :D
Als letzte Rettung wende ich mich nun an euch, mein Problem ist folgendes:
Für ein Projekt möchte ich gerne, dass mein Programm mit meinem Linux-Server(Debian Lenny) kommunizieren kann. Aus diesem Grunde habe ich mir auch ganz brav folgendes Tutorial durchgelesen:
http://www.delphi-library.de/topic_60744.html
Auf meinem eigenen Rechner hat das natürlich auch wunderbar geklappt. Da ich dann aber auch mit meinem Server kommunizieren wollte, habe ich (nachdem Studieren verscheidener Beiträge zu dem Thema aus dem Netz) folgenden Code zusammengebastelt, der dann erfreulicherweise auf meinem eigenen PC auch korrekt funktionierte(damit WINE das zum laufen bringt, sollte es eine Konsolenanwendung sein, daher die Mühe):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116:
| program ChatServer;
{$APPTYPE CONSOLE}
uses SysUtils, ScktComp, Classes, Windows;
type TMainThread = class(TThread) public procedure Run; end;
TServerThread = class(TThread) ServerSocket: TServerSocket; Port: Word; constructor Create; destructor Destroy; procedure OnClientRead(Sender: TObject; Socket: TCustomWinSocket); procedure OnClientConnect(Sender: TObject; Socket: TCustomWinSocket); procedure OnClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); procedure OnServerShutDown(SendText: String); end;
var MainThread: TMainThread; ServerThread: TServerThread; i: Integer; Msg: TMsg;
procedure TMainThread.Run; begin Write(#7); ReadLn; end;
constructor TServerThread.Create; begin inherited Create(True); ServerSocket:=TServerSocket.Create(nil); end;
destructor TServerThread.Destroy; begin ServerSocket.Destroy; inherited Destroy; end;
procedure TServerThread.OnClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin writeln('Client hat verbunden'); Socket.SendText('Moin'); end;
procedure TServerThread.OnClientRead(Sender: TObject; Socket: TCustomWinSocket); begin writeln(Socket.ReceiveText); for i := 0 to ServerSocket.Socket.ActiveConnections-1 do ServerSocket.Socket.Connections[i].SendText(Socket.ReceiveText); end;
procedure TServerThread.OnClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin writeln('Client disconnected'); end;
procedure TServerThread.OnServerShutDown(SendText: String); begin writeln(SendText); end;
begin ServerThread := TServerThread.Create; with ServerThread do begin ServerSocket.OnClientConnect:=ServerThread.OnClientConnect; ServerSocket.OnClientDisconnect:=ServerThread.OnClientDisconnect; ServerSocket.OnClientRead:=ServerThread.OnClientRead; end;
WriteLn('ChatServer'); WriteLn; Write('Port: '); ReadLn(ServerThread.Port);
ServerThread.ServerSocket.Active:=False; ServerThread.ServerSocket.Port:=ServerThread.Port;
try ServerThread.ServerSocket.Open;except ServerThread.ServerSocket.Active:=False; WriteLn('ERROR!'); end;
WriteLn('Server is running.'); while GetMessage(Msg, 0, 0, 0) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; ReadLn;
ServerThread.Destroy; end. |
In WINE resultiert das allerdings in folgende Ausgabe:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| ChatServer
Port: 12345 Application tried to create a window, but no driver could be loaded. Make sure that your X server is running and that $DISPLAY is set correctly. Application tried to create a window, but no driver could be loaded. Make sure that your X server is running and that $DISPLAY is set correctly. Server is running. |
Nach kurzem Debuggen habe ich herausgefunden, dass der Fehler ziemlich sicher beim ServerSocket.Open auftritt! Was zum Teufel geschiet da, was diesen Error hervorrufen könnte? Und wie kriege ich das ganze unter WINE zum laufen?
Denn wenn das erstmal so funktioniert, könnte ich das Tutorial weiter durcharbeiten, um es weiter mit Funktionen auszuschmücken :D
Und wenn das ganze garnicht und auf keinen Fall auf diese Weise realisierbar ist, muss ich das ganze vermutlich wohl unter Lazarus realisieren :( Aber wirklich nur im Notfall, da das für mich Neuland ist :wink: Also, falls ihr mir von vorneherein sagt, dass das nicht möglich ist, benötige ich da hilfe :)
Ich freue mich schon auf eure kompetenten Ratschläge,
MFG cyberbug
Narses - Mo 02.11.09 00:11
Moin!
cyberbug hat folgendes geschrieben : |
| Und wie kriege ich das ganze unter WINE zum laufen? |
Warum das mit WINE nicht funktioniert oder wie man es unter WINE konkret machen muss, kann ich dir nicht sagen, aber dein Code wird sicher so nicht funktionieren. Da sind gleich mehrere dicke Macken drin: Du hast die Execute-Methode deiner Thread-Descendants nicht überschrieben, die tun also nix. Weiterhin kann man einen non-blocking-Socket nicht so ohne weiteres in einen Thread stecken, da das mit der Messageloop nicht funktioniert. Wenn schon ein non-blocking TServerSocket in einem Thread, dann
in diesem hier [
http://www.delphi-library.de/viewtopic.php?t=90333]. :idea:
Es ist vermutlich aber (wg. WINE) besser, wenn du auf blocking-sockets + Threads umsteigst. Das geht dann besser mit den Indy-Komponenten.
cu
Narses
Schwedenbitter - Fr 18.12.09 18:27
cyberbug hat folgendes geschrieben : |
...
Nach kurzem Debuggen habe ich herausgefunden, dass der Fehler ziemlich sicher beim ServerSocket.Open auftritt! Was zum Teufel geschiet da, was diesen Error hervorrufen könnte? Und wie kriege ich das ganze unter WINE zum laufen? |
Der tritt tatsächlich bei ServerSocket.Open auf.
Es liegt daran, dass ein Fensterhandle erzeugt und benutzt wird. [
http://www.delphipraxis.net/post1111463.html#1111463]
Ich gehöre (auch) zu den Bewunderern von Narses und wollte eigentlich anhand seiner Tutorials zu den Sockets ein Server-Client-System schreiben. Da aber sämtliche unserer Server-Software auf einem Linux-System läuft, bin auch ich auf wine angewiesen.
Ich bin noch nicht (erst wenn ich graue Haare bekomme) bereit, eine Win-Lizenz zu kaufen, um es in einer VM ausführen zu lassen. Also suche ich derzeit nach einer anderen Lösung in die Richtung, dass ich wine eben seinen X-Server gebe und alles ist in Butter. Es scheint grundsätzlich zu gehen. Ich bin aber kein Mitgleid bei
Xing [
http://www.xing.com/net/linux/linux-software-allgemein-40759/x-server-als-user-installieren-14415933/] und kann daher nicht weiter nachfragen. Der Initiator des Thread fragt nur, ohne seine Lösungsansätze selbst zu präsentieren :-(
Wenn irgend jemand eine Lösung für das Problem hat: Ich wüsste sie auch gern! Das beschäftigt mich schon seit Tagen. Ich habe Stillstand, weil ich nicht weiter das fertige VCL-Programm auf die Konsole portieren möchte, wenn es hinterher nicht läuft.
Gruß, Alex
Niko S. - Fr 18.12.09 18:34
Und mit den IndySockets geht das auch nicht?
Schwedenbitter - Fr 18.12.09 23:48
Niko S. hat folgendes geschrieben : |
| Und mit den IndySockets geht das auch nicht? |
Ich benutze TurboDelphi. Da kann ich grundsätzlich keine Fremdkomponenten benutzen.
Insoweit verstehe ich bis heute nicht, warum INDY 10 mit TurboDelphi installiert, aber keinerlei Komponenten in der IDE installiert sind!
Das Problem ist ja auch, dass ich das Programm im Grunde fertig habe. Es fehlt "nur noch" die Portierung von einer Server-Application mit Fenster (VCL) in eine Konsolen-Application. Selbst wenn ich jetzt anfange, mich mit den IndySockets zu befassen, dann muss ich wieder ganz von vorn anfangen :-(
Gruß, Alex
Niko S. - Sa 19.12.09 00:38
So ganz von vorne wirst du nicht anfangen müssen...
Außerdem kennst du mit Turbodelphi die Indys nutzen, musst sie nur selbst erstellen.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| uses IdTcpClient; [...] var ClientSkt: TIdTcpClient;
[...] begin ClientSkt := TIdTcpClient.Create(self); end;
[...] begin if Assigned(ClientSkt) then ClientSkt.Free; end; |
Schwedenbitter - Do 07.01.10 21:13
Das ist die Lösung in openSUSE:
1. Man installiert die Pakete, welche Xvfb (Virtual framebuffer X server). Dieser X-Server wurde ausschließlich dazu geschaffen, um auf Maschinen ohne Monitor zu arbeiten und lässt sich prima missbrauchen.
2. Dann lässt man über ein Skript folgendes aufrufen
| Zitat: |
Xvfb :1 &
# ... kurz warten ...
export DISPLAY=:1
# evt noch nen window manager:
# metacity &
wine project1.exe |
Man sieht dann zwar keine Ausgabe oder Fenster, aber man merkt ob es läuft, wenn man sich mit Clients verbinden kann.
Ich danke den Helfern der
openSUSE mailing lists [
http://lists.opensuse.org/opensuse-de/2009-12/msg01228.html]!
Gruß, Alex
Astat - Fr 08.01.10 00:47
Hallo cyberbug, die einfachste Möglichket ist die Verwendung von ein paar Zeilen "berkeley" kompatibler Socket-API.
Läuft überall unter Linux, Unix bis Windows.
Für Delphi hab ich Dir ein Client Sample beigelegt, die Anpassung an Deine Bedürfnisse sollten kein Problem sein.
Wichtig für Dich sind die ioctlsocket, send und recv API's, solltest Du Dir mal kurz reinziehen.
Wenn du die Api halbwegs intus hast, brauchst keine unverständlichen "Black Box Componenten" mehr!!
Tip, vergiss Wine, und Compiliere den Server unter FPC zB. mit Lazarus.
lg. Astat
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!