![]() |
Dateien an PC's senden und empfangen
Hallo Zusammen,
ich versuche mit Delphi 5 in einer Konsolen Anwendung einen Client und einen Server zu programmieren um dann zwischen Server und Client Daten auszutauschen. Nach ein paar Recherchen hatte ich die Idee dafür Sockets zu verwenden, aber irgendwie gibt es dazu keine wirklich gute Beschreibung im Internet wie man sowas auf Konsolenebene anstellt. Ich kenne mich zwar einigermaßen mit Sockets aus, aber Delphi ist für mich noch Neuland. Vielleicht hat jemand eine Idee dazu, oder kennt einen hilfreichen Link. Besten Dank schonmal im Voraus. |
Re: Dateien an PC's senden und empfangen
TTCPServer & TTCPClient von den Indy's. Damit kannst Du Daten zwischen Rechner hin und her schicken.
|
Re: Dateien an PC's senden und empfangen
Hallo, kuck mal da!
![]() Was brauchst den genau? Synchrone oder Asynchrone Übertragung? Was brauchst an Performance (Max Anzahl der Clients, Datenvollumen etc.) ? |
Re: Dateien an PC's senden und empfangen
Also eine Consolen Application für einen asynchronen Socket kann in etwa so aufgebaut werden.
Delphi-Quellcode:
program AsyncClientConsole;
{$APPTYPE CONSOLE} uses windows, SysUtils, messages, uConsoleClass in 'uConsoleClass.pas'; function MainWndProc(ahWnd: HWND; auMsg: Integer; wp: WPARAM; lp : LPARAM): Integer; stdcall; forward; const WM_DATA = WM_USER + 1; WM_CONNECTED = WM_USER + 2; WM_ERROR = WM_USER + 3; var Terminated : Boolean; hWndMain : HWND; TADAMainWindowClass : TWndClass = (style: 0; lpfnWndProc: @MainWndProc; cbClsExtra: 0; cbWndExtra: 0; hInstance: 0; hIcon: 0; hCursor: 0; hbrBackground: 0; lpszMenuName: nil; lpszClassName: 'MyConsoleMainWindowClass' ); procedure WMOnConnected(wp, lp: DWORD); begin writeln('WMOnConnected : ' + PChar(wp)); end; procedure WMOnData(wp, lp: DWORD); begin writeln(PChar(wp)); writeln(inttostr(lp)); end; procedure WMOnError(wp, lp: DWORD); begin writeln('WMOnECSError : ' + PChar(wp)); end; function MainWndProc(ahWnd: HWND; auMsg: Integer; wp: WPARAM; lp: LPARAM): Integer; stdcall; begin Result := 0; if auMsg = WM_DATA then WMOnData(wp, lp) else if auMsg = WM_CONNECTED then WMOnConnected(wp, lp) else if auMsg = WM_ERROR then WMOnError(wp, lp) else if auMsg = WM_CLOSE then DestroyWindow(ahWnd) else Result := DefWindowProc(ahWnd, auMsg, wp, lp); end; function InitAplication : Boolean; begin Result := FALSE; if Windows.RegisterClass(TADAMainWindowClass) = 0 then Exit; hWndMain := CreateWindowEx(WS_EX_TOOLWINDOW, TADAMainWindowClass.lpszClassName, '', WS_POPUP, 0, 0, 0, 0, 0, 0, HInstance, nil); if hWndMain = 0 then Exit; (******** Hier nun Socket Connection durchführen und Messaging mit Windowsmessages und oder mit Callback, je nach Geschmack ********) Result := TRUE; end; procedure CleanupAplication; begin if hWndMain <> 0 then begin DestroyWindow(hWndMain); hWndMain := 0; end; end; procedure RunAplication; var MsgRec : TMsg; begin while GetMessage(MsgRec, 0, 0, 0) do begin TranslateMessage(MsgRec); DispatchMessage(MsgRec) end; Terminated := TRUE; end; begin InitAplication; try RunAplication; finally CleanupAplication; end; end. |
Re: Dateien an PC's senden und empfangen
Vielen Dank für die schnellen Antworten und dem Beispielprogramm. werd das gleich mal ausprobieren. :-)
also ich will am ende quasi von einer zentralen stelle an mehrere clients signale schicken und deren antwort empfangen und auswerten. wie so eine art telefonanruf. ich schicke ein signal(wähle die nummer der person die ich erreichen will), es klingelt bei dem anderen, dann nimmt er ab und ich bekomme z.B. das signal "Hallo" zurück. die verbindung muss nur so lange bestehen, bis die antwort eingegangen ist, danach kann sie sofort beendet werden. die anzahl der clients kann ich noch nicht genau sagen, aber da die verbindungen eh schnellstmöglich wieder getrennt werden ist sicher keine allzu große zahl nötig. achso, noch zum datenvolumen. also ich denke das max ein paar 100 kbyte ausreichen sollten. das grösste was dabei übertragen werden könnte wäre eine textdatei in der eigentlich so gut wie nichts drin stehen muss. ansonsten werden ja nur signale übertragen und die sind ja bei weitem nicht so groß. |
Re: Dateien an PC's senden und empfangen
Ok, alles fix und fertig!
Schön gekapselt in DLL's (Client-Server) Synchroner und Asynchroner Transport. Hochlasttauglich (Async ist mit 10000 Clients) getestet. Sync skaliert excellent (mit 2 X Quad-Cores Xeons) getestet. ![]() ![]() Have a lot of fun! |
Re: Dateien an PC's senden und empfangen
wow
ich hoffe ich steig da jemals durch was du hier gebastelt hast. wie gesagt, bin in delphi noch anfänger und wäre mit einer simplen "stino"-lösung die man leicht nachvollziehen kann auch zufrieden gewesen ;-) ich danke dir aber auf jedenfall für deine mühen und werd mich mal ans "lesen und verstehen" ran machen :-) |
Re: Dateien an PC's senden und empfangen
Ich hab meinen ersten/aktuellen Server in seinen Grundzügen quasi so gestaltet:
Delphi-Quellcode:
Wobei man den Server (TIdTCPServer, Sockets oder was auch immer) auch in den THandler hineinverlagern könnte, also diesen in .Create erstellen und in .Destroy freigeben.
Program HiddenServer;
{$APPTYPE CONSOLE} {$R *.res} Uses Windows, SysUtils, Classes, Forms, Graphics, IdContext, IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer; Type THandler = Class(TComponent) Public Constructor Create(AOwner: TComponent); Destructor Destroy; Override; Procedure ServerConnect(Context: TIdContext); Procedure ServerExecute(Context: TIdContext); Procedure ServerDisconnect(Context: TIdContext); Procedure ServerStatus(Sender: TObject; Const Status: TIdStatus; Const StatusText: String); ... End; Constructor THandler.Create(AOwner: TComponent); Begin Inherited; ... End; Destructor THandler.Destroy; Begin ... Inherited; End; Procedure THandler.ServerConnect(Context: TIdContext); Begin WriteLn('#Connect: ', Context.Binding.PeerIP, ':', Context.Binding.PeerPort); ... End; Procedure THandler.ServerExecute(Context: TIdContext); Begin ... If (beenden) Then Application.Terminate; ... End; Procedure THandler.ServerDisconnect(Context: TIdContext); Begin WriteLn('#Disconnect: ', Context.Binding.PeerIP, ':', Context.Binding.PeerPort); ... End; Procedure THandler.ServerStatus(Sender: TObject; Const Status: TIdStatus; Const StatusText: String); Const X: Array[TIdStatus] of String = ('haResolving', 'hsConnecting', 'hsConnected', 'hsDisconnecting', 'hsDisconnected', 'hsStatusText', 'ftpTransfer', 'ftpReady', 'ftpAborted'); Begin WriteLn('#State (', X[Status], '): ', StatusText); End; Var Handler: THandler; Server: TIdTCPServer; Function HandlerRoutine(CtrlType: LongWord): LongBool; StdCall; Begin FreeAndNil(Server); FreeAndNil(Handler); Result := False; End; Begin SetConsoleCtrlHandler(@HandlerRoutine, True); Try Application.Initialize; Handler := THandler.Create(Application); Try Server := TIdTCPServer.Create(Handler); Server.OnConnect := Handler.ServerConnect; Server.OnExecute := Handler.ServerExecute; Server.OnDisconnect := Handler.ServerDisconnect; Server.OnStatus := Handler.ServerStatus; Server.DefaultPort := 50000; Server.Active := True; Try Repeat Application.ProcessMessages; Sleep(10); Until Application.Terminated; Finally FreeAndNil(Server); End; Finally FreeAndNil(Handler); End; Except On E:Exception do WriteLn(E.ClassName, ': ', E.Message); End; End. Ist im Grunde wie bei uoeb7gp (#4), nur daß dort die Verwaltung des Nachrichtenfensters und die Nachrichtenbehandlung Application überlassen und für die Verbidung direkt eine der fertigen Internetkomponenten verwendet wird. PS: die HandlerRoutine ist für denn Fall, daß das Konsolenfenster über [X] geschlossen wird, also damit auch in diesem Fall alles ordnungsgemäß beendet wird. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz