also ich komme mit diesen Indy Komponenten einfach absolut nich klar...
ich habe in meinem Projekt einen Server und ~10 Clienten.
Nun soll der Client eine anfrage an den Server schicken, und der schickt die antwort(en) zurück... Soweit kein problem, bisher hab ich das mit WinSock gemacht, ging auch ganz ok, nur das dabei immermal daten verloren gingen wenn viele anfragen gleichzeitig waren...
Deswegen wollte ich nun auf Indy umsteigen, hab aber absolut ganz und garkeine ahnung wie das da geht... die Demos sagen mir rein garnix und Tutorials finde ich auch keine gute
Kann mir mal wer erklären wie ich sowas wie oben beschrieben mit IndyKompos mache??? Also was muß ich da einstellen etc, welche Events blabla..
Au'revoir, Aya~
PS: Mit dem WinSock hab ich's so gemacht das das ServerProg/Client beide sowohl einen Client als auch Server drin hatten...
ClientProg-Client schickt an den ServerProg-Server "Hallo ich bin da" -> ServerProg-Server sagt dem ServerProg-Client "Antworte dem mal".. und ServerProg-Client schickt an den ClientProg-Server "Willkommen "...
So in der art, wie mach ich das mit Indy??? :unsure:
Registriert: Sa Mai 04, 2002 19:48 Beiträge: 3830 Wohnort: Tespe (nahe Hamburg)
Quelle ist von Delphisource.de, hatg mir sehr geholfen, als ich da Eingestiegen bin: <a href='http://www.tutorials.delphi-source.de/indy/file002.shtml' target='_blank'>Delphi-source.de</a>
_________________ "Light travels faster than sound. This is why some people appear bright, before you can hear them speak..."
PS: Bitte!! Ist sehr wichtig... muß das Programm bis Mittwoch fertig haben, und solange das mit dem Netzwerk nich fehlerfrei geht kann ich am rest schlecht weitermachen...
Registriert: Sa Mai 04, 2002 19:48 Beiträge: 3830 Wohnort: Tespe (nahe Hamburg)
Wie ist doch wirklich alles gut erklärt dort! Du gibst dem Client host und port, connectest und kannst dann überr die Verbindung mit Readln Nachrichten abrufen. Der Server selst arbeitet im Executre und liefert die Nachricht, die für den client bestimmt ist (das muss man ja selbst verwalten). Habe den Code von delphi-source.de fast 1:1 hochgeladen: <a href='http://www.phobeus.de/temp/indytcp.zip' target='_blank'>tcp indy</a>
_________________ "Light travels faster than sound. This is why some people appear bright, before you can hear them speak..."
das wie du es in deinem Beispiel gemacht hast, hatte ich ja auch kapiert...
Aber bei dir sagt der client nur "ich bin da"... aber ich brauche das so das der Client sage "Gib mir die und die Daten" und der Server muß je nachdem was der Client sagt etwas anderes schicken...
Wie mach ich das???
Weil im Client nen WriteLN(Bla) und direkt dannach nen ReadLN machen geht ja net... oder?
Registriert: Sa Mai 04, 2002 19:48 Beiträge: 3830 Wohnort: Tespe (nahe Hamburg)
Nun setze doch mal deine Fantasy in Gang ;D Ich werde das ganze einfach mal sehr bildlich erzählen, glaube wenn Du nun noch wissen über Flags und Strukturen hast, wirst Du selbst schnell ne Lösung finden ;D
Client a sagt "Ich will wissen, wer da ist!" Server erkennt, dass a nicht in List ist, setzt a in Liste und antwortet mit List. Client a sagt "empfangen". Server sagt "k, verdrück dich" Client b sagt "Ich will, wissen, wer da ist!" Server b erkennt, dass b bereits vor 10 Sekunden gefragt hat und banned b.
Speichere am besten die IP um die Rechner zu identifizieren. Je nachdem was, für eine Anfrage kommt, wird was anderes gesendet. Notfalls könntest auch client und server in einer app packen, so dass sie nur die IP ansteuern und jeweils auf die Anfrage die Antwort senden. Macht ne Sinn, wenn Du Applikations haben willst, die eigenständig asrbeiten sollen und keinen zentralen Server verwenden sollen.
_________________ "Light travels faster than sound. This is why some people appear bright, before you can hear them speak..."
Registriert: Mo Jan 20, 2003 20:10 Beiträge: 424 Wohnort: nähe Starnberg
Hi Aya,
ich verwende Indy in einem Replikationsprotokoll für eine Datenbank. Was mich an Indy am Anfang verwundert hat, ist, das der Requests der Clients in einem Thread -Kontext ablaufen. Damit hast Du natürlich die Probleme, die mit einem Thread zusammenhängen.
Eine Server - Komponente aufs Formular. In der OnExecute - Property ein Doppelklick, schon hast Du deine Methode, die ein(!) Request abarbeitet. Diese Methode entspricht einer Thread.Execute - Methode, also direkte Aufrufe mit der VCL sind problematisch und globale Listen immer mit TThreadList. Diese Requests können parallel ausgeführt werden.
In dieser Methode gehst Du linear vor. AThread.Connection enthält den Verbindungsdaten zu deinem Client.
Mit AThread.Connection.ReadLn(EOL, MaxTimeout) liest Du Daten von deinem Client, mit AThread.Connection.WriteLn schreibst Du die Antwort an deinen Client, mit AThread.Connection.Disconnect schliest der Server die Verbindung.
1. Befehl vom Client auslesen 2. Analysieren 3. Ergebnis an Client senden 4. Warten auf Bestätigung 5. Entweder weiter mit 1 oder Verbindung beenden.
Mein Problem is nich wie ich am Server die daten vom Client speicher, oder wie ich nen Event mache etc.. *g*
Sondern mein Problem ist ganz simpel und einfach das ich keine ahnung von den IndyBefehlen habe.
Also... Client sagt zum Server "Gib mir mal die liste der User" Server schickt ihm die liste der User
mein ganz und gar aller einzigstes Problem an der sache ist nun.. äh.. ich sag's anders *g* Erstmal macht der Client
Code:
WriteLN("Los, gib mal Userliste")
..ja?? Dann im OnExecute vom Server:
Code:
procedure OnExecute...;
begin
msg:=AThread....ReadLN;
if msg = "Los gib mal userliste" then
WriteLN(UserListe);
end;
so, ja?? Soweit sogut...
jetzt fehlt mir im Client aber noch ein ReadLN.. wo muß das hin?!
Denn direkt nach dem WriteLN bringt es doch nix, denn da kann es ja sein das dank langsamen Netzwerkes der Server nochnichmal den Request bekommen hat... oder??
Mein Problem is also nur, wo pack ich das ReadLN vom Client hin?
aaaaaber... wenn jetzt im OnExecute vom Server mehrere Zeilen geschrieben wurden (also z.B. 3x WriteLN) bekomme ich so nur die letzte raus... was mach ich da?
Au'revoir, Aya~
PS: Ist es 100%ig sicher das das was ich im OnExecute mit WriteLN mache, wirklich nur der Client bekommt der den Request gemacht hat, oder muß ich da nochwas beachten?
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Aya hat geschrieben:
Denn direkt nach dem WriteLN bringt es doch nix, denn da kann es ja sein das dank langsamen Netzwerkes der Server nochnichmal den Request bekommen hat... oder??
Klar. Warum sollte das denn nicht gehen?
Hier mal ein kleines Sample (innerhalb von 5 Minuten erstellt und 100% funktionsfähig)
PS: Es wird für jede Verbindung ein eigener Thread abgespalten und diese besitzt eine eigene connection. Alles was du an Connection.Write sendest bekommt auch nur ein Client. Das geht vom Netzwerkprotokoll schon gar nicht anders. (wenn ich mich nicht irre)
klar.. wenn ich 2x ReadLN aufrufe les ich auch beide Zeilen... aber anders geht das nich???
Bei mir isses so das es mal nur 1 Zeile sein kann, mal 20.... (ok, ich könnte jedesmal als erste Message einfach nen Count schicken, also wieviele Zeilen noch kommen, aber erstmal fragen ob's was besseres gibt *g*)
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Nö. Du wirst um diesen Count kaum drum herum kommen. Du könntest natürlich lesen so lange wie etwas kommt uns sobald du einmal einen Timeout bekommen hast dann gibt es nichts mehr. Aber das wäre äußerst ineffizient! Nach Möglichkeit solltest du sogar die einzelnen Zeilen Binär codieren. Je nachdem wie häufig du sie sendest und wie komplex das ist was sich dort drin befindet. Einen einzelnen Namen bräuchte man nicht groß in Binär umwandeln. Aber wenn das eine komplexe Struktur ist sollte man das noch einmal überdenken.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Das ist keine Autofehlermeldung das nennt sich Exception und ist eine Wunderwaffe. Wird von vielen C++lern nicht verwendet weil es "zu umständlich sei"!
Nicht abgefangene Exceptions werden spätestens von der Application abgefangen. Bei Quellen die Fehler produzieren können (wie "kein Server vorhanden") sollte man das try ... except bzw. try ... finally einsetzen. Try ... except wird nur augerufen wenn ein Fehler aufgetreten ist. Try ... finally wird immer aufgerufen sogar wenn ein Fehler aufgetreten ist. Wird eingesetzt um Resourcen wieder frei zu geben.
Code:
uses
... IdException;
procedure TForm1.Button1Click(Sender: TObject);
begin
try
IdTCPClient1.Connect;
except
on E: EIdSocketError do begin
ShowMessage('Mir scheit als gäbe es keinen Server ...');
end;
on E: EIdAlreadyConnected do begin
ShowMessage('Döspadel du bist doch schon eingelockt!');
end;
end;
end;
So kannst du abfangen welcher Fehler aufgetreten ist. Du kannst den Exceptblock noch mit beliebigen Exceptions und Aktionen erweitern.
Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.