Entwickler-Ecke

Delphi Tutorials - Terminatorzeichen-Protokoll-Tutorial / Teil 1 (Sockets)


Narses - Mi 11.01.06 10:49
Titel: Terminatorzeichen-Protokoll-Tutorial / Teil 1 (Sockets)
Narses´ Netzwerk-Tutorials - Navigation
  1. FAQ-Beitrag: Socket-Komponenten nachinstallieren (ab D7) [http://www.delphi-library.de/topic_64438.html]
  2. Netzwerk-Basics - Minimaler Chat für Anfänger [http://www.delphi-library.de/topic_60744.html]
  3. hier :arrow: Terminatorzeichen-Protokoll - Grundlagen (Teil 1)
  4. Terminatorzeichen-Protokoll - Erweiterungen (Teil 2) [http://www.delphi-library.de/topic_65487.html]
  5. Binär-Protokoll - Für Fortgeschrittene [http://www.delphi-library.de/topic_66706.html]
  6. Netzwerk-Spiel - Multiplayer TicTacToe [http://www.delphi-library.de/topic_72573.html]
  7. UDP LAN-Chat - Der Chat ohne Server [http://www.delphi-library.de/topic_56272.html]

Terminatorzeichen-Protokoll-Tutorial Teil 1 - Grundlagen

Was ist ein Kommunikations-Protokoll?

In diesem Tutorial wird ausführlich und für Anfänger in Sachen "Netzwerk" geeignet erläutert, was ein Kommunikations-Protokoll ist, wie man ein eigenes Protokoll entwickelt und wozu man sowas gebrauchen kann. Es baut auf den TServerSocket-/TClientSocket-Komponenten auf.

Warum sollte ich mir dieses Tutorial ansehen?
In diesem Zusammenhang:



Viel Erfolg damit,

cu
Narses


History:

Änderungen in V4.00 vom 22.09.2006: -Milestone-Edition-
Da dieses Tutorial sich konkret an Anfänger in Sachen Netzwerk richtet, habe ich es an einem hoffentlich strategisch günstigen Punkt in zwei Teile aufgeteilt (was die größte Änderung in dieser Version darstellt). Die komplette Version-History sprengt den Rahmen dieses Beitrags...
Hinweis: Ältere Versionen heißen möglicherweise noch "Protokoll-Chat-Tutorial". Im Rahmen der Entwicklung hat sich aber die Namensänderung ergeben, da mir der alte Name zu ungenau war. Diese veralteten Versionen können bedenkenlos "entsorgt" und durch die aktuelle Version ersetzt werden.

Kommentare zum Tut sind hier durchaus erwünscht!

Falls die Anhänge unten nicht angezeigt werden, Seite (ggfs. auch mehrfach) neu laden.


Arno Nym - Mi 11.01.06 14:36

Hi,
das hast du wirklich gut gemacht ! Hab das pdf eben mal schnell überflogen, scheint wirklich alles wichtige drin zu sein, obs funktioniert habe ich noch nicht getestet, aber du ja sicherlich :)
Dank deiner Hilfe werden jetzt sicher ein paar posts weniger zu diesem Thema nötig sein. Bin zwar selbst nicht unbedingt darauf angewiesen, aber als Einsteiger vor ein paar jahren hätte ich so ein walkthrough selbst gut gebrauchen können.
Also Danke nochmal das du dir soviel Mühe gemacht hast !
(Im Forum wird eh zu wenig gelobt..immer nur an kleinigkeiten rumgenörgelt :)
Deswegen nochmal ein Lob und viele Grüße:
Arno Nym


Jojojoxx - Mi 11.01.06 15:35

Hi!

Vielen Dank!!!!
Werd mir das in den nächsten Tage auch mal zu Gemüte führen! :D

mfg

Jojo


Narses - Do 19.01.06 14:26

Moin!

Neue Version V2.00! Details, wie immer, im ersten Posting. Es hat sich wirklich sehr viel geändert, ist auf jeden Fall einen zweiten Blick wert! :D

cu
Narses


Seraph - Do 02.02.06 10:25

Und wo bekomme ich die 2.00 Versionen der Sockets?


Narses - Do 02.02.06 10:46

Moin!

user profile iconSeraph hat folgendes geschrieben:
Und wo bekomme ich die 2.00 Versionen der Sockets?

:gruebel:

Ich kann dir nicht folgen, hast du die TServerSocket/TClientSocket-Kompos nicht, oder was meinst du?

cu
Narses


Seraph - Do 02.02.06 10:48

Ja genau!
Zumindest nicht auf meiner Workstation!
(Delphi7)

Gruß
Seraph


Narses - Do 02.02.06 10:50

Moin!

Genau dafür gibt es einen entsprechenden Hinweis im Tut. :wink: Guckst du Suche in: Delphi-Forum, Delphi-Library DCLSOCKETS70.BPL

cu
Narses

//EDIT: Es gibt jetzt (V2.01) auch ein eigenes Kapitel im Tut, das ausführlich zeigt, wie man die Sockets nachinstalliert.


Narses - Mo 13.02.06 02:43

Moin!

Neue Version 2.01 released. Details, wie immer, im ersten Posting.

cu
Narses


Hellcode - So 19.02.06 18:07

Erstmal vorweg: Sehr gutes Tutorial! Die Protokollfragen behandelst du sehr ausführlich und kompetent. Allerdings finde ich, auch wenn es in dem Tut hauptsächlich ums Protokoll und die Technik geht, solltest du, gerade wenn du Anfänger ansprichst, nicht die Details vernachlässigen. Zum Beispiel sollte es den "IP?"-Button meiner Meinung aus Sicherheitsgründen niemals im Client einbauen. Auf die tatsächliche IP der Chatter sollte nur der Server Zugriff haben. Ausserdem sollte immer eine Sperre des für Systemnachrichten konstanten Nickname eingerichtet werden, soll heißen, ein Client sollte sich nicht (in diesem Falle) "System" nennen können. Sind ja nun wirklich keine großen Angelegenheiten, und somit auch nicht schwer zu coden. Ich habe dein Tutorial muss ich gestehen nicht ganz gelesen, vielleicht gehst du auf die von mir angesprochenen Probleme ja an den entsprechenden Stellen ein. Trotzdem: Ausgesprochen gutes Tutorial, was ganz und gar kein weiteres Sandkorn im Strand der vielen Socket/Internet-Programmierung-Tuts darstellt!


Narses - Mo 20.02.06 00:07

Moin!

Danke für das Lob! :D

user profile iconHellcode hat folgendes geschrieben:
den "IP?"-Button meiner Meinung aus Sicherheitsgründen niemals im Client einbauen. Auf die tatsächliche IP der Chatter sollte nur der Server Zugriff haben.

Die IP deines PCs im Internet ist kein Geheimnis, sonst könntest du ja gar nicht Kommunizieren. Wenn du Angst hast, dass jemand mit deiner IP was "böses" anstellt, dann solltest du dir eine vernünftige Firewall anschaffen. :wink: IMHO ist das kein sicherheitsrelevantes Problem, für die Sicherheit ist jeder PC-Betreiber schon selbst zuständig. Du kannst meine IP gerne jederzeit haben, es wird dir nix nutzen... :wink:

user profile iconHellcode hat folgendes geschrieben:
Ausserdem sollte immer eine Sperre des für Systemnachrichten konstanten Nickname eingerichtet werden, soll heißen, ein Client sollte sich nicht (in diesem Falle) "System" nennen können.

Danke für den Hinweis, hier ist er genau richtig. Wer das Tut als Ansatz für ein reales System einsetzen möchte, kann den Hinweis auch sicher gut gebrauchen. Allerdings ist er im Tut nicht relevant, da, wie du schon richtig erkannt hast, es dort um das Protokoll und die Technik geht. Die Nicknames spielen genau genommen keine Rolle und der Server ist eigentlich gar nicht als Frontend zur Kommunikation vorgesehen, was auch so im Tut klar dargestellt ist. Das Thema geht schnell viel tiefer, und das ist das Problem: wenn der Name "System" nicht zulässig sein soll, dann wäre auch gleich eine komplette Benutzerverwaltung notwendig, die ebenfalls doppelte Nicks ausschließt usw. - das führt aber viel zu weit und lenkt vom Thema Protokoll ab. :wink:

user profile iconHellcode hat folgendes geschrieben:
Ich habe dein Tutorial muss ich gestehen nicht ganz gelesen

Vielleicht solltest du das nachholen... :wink: (was, wenn da tatsächlich auch noch was Neues für dich drin stehen sollte... ?)

Trotzdem nochmal vielen Dank für dein Lob!

cu
Narses


Hellcode - Mo 20.02.06 15:24

Zitat:

user profile iconHellcode hat folgendes geschrieben:
Ich habe dein Tutorial muss ich gestehen nicht ganz gelesen

Vielleicht solltest du das nachholen... :wink: (was, wenn da tatsächlich auch noch was Neues für dich drin stehen sollte... ?)


Son Schwachsinn :dance:

Nein, im ernst das Tutorial zeigt mir das du sehr viel Ahnung hast, da kann ich mir auf jeden nochwas abschneiden. :flehan: Ich werds mir nochmal ganz durchlesen!

Moderiert von user profile iconraziel: Überflüssige Zeilenumbrüche enternt.


snack - Di 21.02.06 20:08

Vielleicht fehlt als Ausblick noch ein Hinweis auf IRC (Internet Relay Chat),
dass unter RFC 1458 (http://www.ietf.org/rfc/rfc1459.txt) zu finden ist.

Man kann zumindest einige Ideen von dem relativ umfangreichen IRC-Protokoll abschauen.


BadAzz - Fr 24.02.06 22:49

klappt das auch über internet oder nur im lokalen netzwerk?


Narses - Sa 25.02.06 14:37

Moin!

user profile iconBadAzz hat folgendes geschrieben:
klappt das auch über internet oder nur im lokalen netzwerk?

Das sollte auch über das Internet klappen; wenn ein (DSL-)Router im Einsatz ist, braucht der Server noch ein Portforwarding [http://www.delphi-library.de/topic_Portforwarding++Eine+kleine+Einfuehrung_80904.html] (heißt manchmal auch "virtual Server"), sonst kommen die Clients nicht ran.

Das UDP-Chat-Tut [http://www.delphi-library.de/topic_UDPProtokollChatTutorial+V100_56272.html] läuft (so wie dort mit Broadcasts realisiert) nur im LAN.

cu
Narses


Paddymann - Do 09.03.06 17:01

hoI!
Finde die Tutorials ebenfalls super!

Habe aber jetzt beim WinSocketTutorial das Problem, dass er mir beim Compilieren des Server-Parts eine Fehlermeldung ausgibt. Nämlich:
UndefinierterBezeichner:'AddItem'
UndefinierterBezeichner:'Count'
Er bezieht sich dabei auf den Code Clients.AddItem... bzw. Clients.Count... der ListBox.

Kann mir da jemadn helfen? Ich benutze Delphi5 Professional, vllt hat das damit ja was zu tun.

mfg
patti


Narses - Di 21.03.06 02:30

Moin!

user profile iconPaddymann hat folgendes geschrieben:
Finde die Tutorials ebenfalls super!

Danke! :D

user profile iconPaddymann hat folgendes geschrieben:
UndefinierterBezeichner:'AddItem'
UndefinierterBezeichner:'Count'
Er bezieht sich dabei auf den Code Clients.AddItem... bzw. Clients.Count... der ListBox.
[...]
Ich benutze Delphi5 Professional, vllt hat das damit ja was zu tun.

Kann sein, dass D5 das noch nicht kann, dann mußt du das mit

Delphi-Quelltext
1:
Clients.Items.AddObject()                    
und

Delphi-Quelltext
1:
Client.Items.Count                    
runterbrechen. Schau mal, ob das so klappt.

cu
Narses


fidionael - Do 23.03.06 14:56

Das Tutorial ist bestimmt spitze und nachdem ich es mir durchgelesen hab, bin ich zum Schluß gekommen, dass es auch das mit Abstand am besten strukturierte und verständlichste in dieser Richtung ist, das mir bis jetzt untergekommen ist :)

Leider habe ich ein kleines Problem bei der Anwendung dessen was du so beschreibst, das Problem habe ich hier [http://www.delphi-forum.de/viewtopic.php?t=57133] beschrieben.

Schonmal vielen Dank!


-Pl- - Do 23.03.06 22:23

Hi,

ich hab das Tutorial jetzt zu 3/4 durchgearbeitet und ich find es (bis auf einige kleine Schönheitsfehler in der Orientierung) wirklich sehr sehr gut, ich bin gut mitgekommen habe alles soweit verstanden (und ich bin noch nicht soo gut ;) ).

Wo ich allerdings Probleme habe ist diese neue Unit zu finden, die is bei mir nämlich nicht im Delphi Ordner ...

Fazit: Einsame Spitze !!

Pl


Narses - Do 23.03.06 23:23

Moin!

user profile icon-Pl- hat folgendes geschrieben:
ich find es (bis auf einige kleine Schönheitsfehler in der Orientierung) wirklich sehr sehr gut, ich bin gut mitgekommen habe alles soweit verstanden (und ich bin noch nicht soo gut ;) ).

Danke für das Lob! :D Wenn es auch gerade für Anfänger hilfreich ist, habe ich mein Ziel erreicht. ;)

user profile icon-Pl- hat folgendes geschrieben:
Wo ich allerdings Probleme habe ist diese neue Unit zu finden, die is bei mir nämlich nicht im Delphi Ordner ...

Ähm, sprichst du jetzt von den Socket-Komponenten? Welche Delphi-Version du verwendest, hast du übrigens auch noch nicht "verraten"... ;)

cu
Narses


fidionael - Do 23.03.06 23:28

Ich kriege langsam einen Nervenzusammenbruch :(

Nun habe ich endlos recherchiert und von irgendeiner polnischen Seite Delphi 7 PE runtergeladen und registriert, nun finde ich dort nicht einmal das Socket-Package... Ist das nur bei Professional dabei, oder ist nur die Version die ich hab stark abgespeckt worden? Kann mir nicht jemand einfach die erforderliche Komponente für Delphi 7 oder 2005 zum Download anbieten? ;)

Mfg


-Pl- - Fr 24.03.06 00:11

Wie du in dem Tutorial angegeben hast nutze ich die Version Delphi 7 (Enterprise, oder so glaub ich).

Ohne die Socket Komponenten wäre ich bestimmt nicht so weit gekommen ;)
Nein ich meine die neue Stringlist, die man braucht um das mit dem Timing hinzubekommen (aus Tuto gelernt hat ;)).

Da du ja nach den Schönheitsfehlern fragtest hab ich mir die Mühe gemacht und bin das Tut nochmal durchgegangen:

- bei den Bildern zum Aufbau der Oberfläche fehlen die Namen der Buttons, muss man nachschauen, ist nicht so schwer, aber fällt halt auf
(ich sehe gerade, dass du dazu was darunter geschrieben hast, aber man merkt sofort das das da fehlt weil die anderen sachen ja da stehen)
- vielleicht noch ein kleiner Hinweis was man für Host eingeben kann (also IP und so weit (auch wenn das eigtl alle wissen sollten))
- bei 4.9 war mir nicht ganz klar ob in Server oder in Client

Mehr ist mir jetzt leider nicht aufgefallen, weil ich das jetzt ja alles verstehe, ausserdem hab ich das nurnoch mal überflogen.
Ich hoffe das sind halbwegs sinnvolle Punkte. Ich werde beim weiterarbeiten mehr darauf achten.


Narses - Mo 12.06.06 18:54

Moin!

Neue Version 2.02 released. Details, wie immer, im ersten Posting.

cu
Narses


Delphi_Schüler - Di 20.06.06 22:00

dieses Tut ist extrem gut, habs endlich geschaft mal variabeln übers internet zu schicken.

Hab aber ein prop

ich möchte eine flüsterfunktion hinzufügen

ich hab ne combobox im client hinzugefügt. je nachdem welche ip (später nicknamen) ich anwähle, wird eine andere zahl und einem buchstagen vor die nachricht automatisch hinzugefügt, die nachher wieder davon getrennt wird.
Die nachricht wird dann an die person geschickt und an den rest nicht. Aber die nachricht wir an alle gesendet.

z.B. a0message (für alle)
a1message (für user der die erste stelle im serverprogramm eingestellt ist)
...

die trennung

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  var
    MyMessage,text: String;
    i: Integer;
    a:char;
begin

  // Nachricht lesen und davor die IP des Absenders setzen
  text:=Socket.ReceiveText;
  a:=text[1];
  text := copy(text,3,length(text)-1); //hab ich aus dem internet, funktioniert aber
  MyMessage := Socket.RemoteAddress+': '+text;


und das Weiterschicken


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  Log.Lines.Add(MyMessage); // Nachricht lokal ausgeben
  // und an alle verbundenen Clients senden
  if a='0' then
  for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
    ServerSocket1.Socket.Connections[i].SendText(MyMessage)   
  else  ServerSocket1.Socket.Connections[( Ord(a) )].SendText(MyMessage);


geht das überhaupt mit socket
oder muss ich die nachricht an alle schicken lassen und im client die nachricht anzeigen oder löschen lassen. (dann ist aber mehr internetverkehr)


fidionael - Di 20.06.06 22:07

Ja, man kann auch Daten nur an bestimmte Verbindungen schicken, aber bist du dir sicher, dass du weißt, was du tust? Der Befehl Ord('x') gibt dir den Wert für das eingegebene Zeichen in der Ascii-Tabelle zurück (also bei 'x' 78 und bei '0' 48 ). Meinst du nicht vielleicht eher sowas wie StrToInt(a)?!

Mfg


Delphi_Schüler - Di 20.06.06 22:10

hab hier gesucht wie man char zu integer und dass war das erste was kam :lol:

PS ich bin mir überhaupt net dabei sicher, kenn mich mit netzwerk in delphi überhaupt net aus. Bin beim normalem programmieren besser


Delphi_Schüler - Di 20.06.06 22:24

hab den programtext umgeschrieben und jetzt gehts einbandfrei. -.-

Ich Hasse es wenn durch so ein kleiner Fehler alles net geht, delphi den Fehler nicht verständlich ausdrückt und ich keine ahnung hab was von den vielen schweren sachen, die ich zum ersten mal benütze, falsch ist und dann ist es wiedermal SO EIN KLEINER SCHE** FEHLER ALLES LAHMLEGT!


Narses - Di 20.06.06 22:24

Moin!

user profile iconDelphi_Schüler hat folgendes geschrieben:
dieses Tut ist extrem gut

Danke. :D

user profile iconDelphi_Schüler hat folgendes geschrieben:
ich möchte eine flüsterfunktion hinzufügen

Bin ich im falschen Film oder du? ;) Ist doch in Kapitel 6.3 erklärt... ? :gruebel:

Oder meinst du das Anfänger-Tut aus der FAQ? :think:

cu
Narses


Delphi_Schüler - Di 20.06.06 23:05

ich wollt es mir auf diese aur es einfach machen, damit ich nicht die kontrolle durch unbekante komponente verliere. Außerdem will ich durch die char zeichen vor den masseges später noch mehr steuern lassen.


Narses - Di 20.06.06 23:13

Moin!

user profile iconDelphi_Schüler hat folgendes geschrieben:
ich wollt es mir auf diese aur es einfach machen

Wenn ich mir den Code da oben ansehe, dann bezweifle ich, dass das im Endeffekt einfacher werden kann. :? Sorry, aber so wird das nix. :|

user profile iconDelphi_Schüler hat folgendes geschrieben:
Außerdem will ich durch die char zeichen vor den masseges später noch mehr steuern lassen.

Dann solltest du dringend das Protokoll-Chat-Tutorial in Angriff nehmen, dein Ansatz mit den Chars ist genau der Grund, warum ich dieses Tut hier geschrieben habe - das wird nämlich nix, so wie du ansetzt. :( Ehrlich... ;)

cu
Narses


Narses - Do 22.06.06 01:53

Moin!

Neue Version 3.00 released. Details, wie immer, im ersten Posting.

Wichtigste Neuerung: Binärdatentransfer als Erweiterung (-> Dateitransfer, Bilder). :D

cu
Narses


BigBasti - So 02.07.06 22:20

Wie kann ich denn am einfachsten eine Möglichkeit für den Server erstellen, mit deren Hilfe er einen Klienten kicken kann? Worauf muss ich dabei so achten? Ist es überhaupt möglich die Verbindung zu genau einem bestimmten Klienten zu beenden?

Gruß,
Sebastian


Narses - So 02.07.06 23:27

Moin!

Gezieltes Trennen von Verbindungen (Kick) und Blockieren von Verbindungen (Ban) sind jetzt im zweiten Teil des Tutorials [http://www.delphi-library.de/topic_TerminatorzeichenProtokollTutorial++2+Sockets+v100_65487.html] ausführlich enthalten. ;)

cu
Narses


BigBasti - Mo 03.07.06 20:27

genial, funktioniert perfekt! vielen dank :-)))

muss dich wirklich nochmal für das geniale tutorial loben, hat mir unheimlich weitergeholfen!


BenBE - Mo 03.07.06 21:44

@NArses: Ist das Absicht, dass V3.00 erst mitte August veröffentlicht wurde?


Narses - Mo 03.07.06 23:02

Moin!

@user profile iconBigBasti: Danke für das Lob. :D Schön, wenn´s dir geholfen hat. :zustimm:

@user profile iconBenBE: Öhm... :? ist natürlich ein Tiepvelher... du merkst aber auch alles... ;)

cu
Narses


Coder - So 09.07.06 15:39

Vielen Dank für dein Tutorial!
Es hat mir echt verdammt viel weitergeholfen. :wink:
Ich freu mich schon auf dein Binärdatentutorial.

MfG, Coder


Born-to-Frag - Mo 17.07.06 22:46

Sieht schonmal nicht schlecht aus die neue Version :zustimm:

Dann warte ich mal bis das Binärprotokoll-Tut fertig ist :zustimm: , sieht ja schonmal nicht schlecht aus!


GimbaR - So 23.07.06 11:04

Moin,
ich wollte mir eben dein tut durchlesen, da is mir gleich am Anfang folgendes aufgefallen:
Zitat:
Version 3.00 vom 22.08.2006


.08 ??? Haben wir schon August? Na klar bin ich noch etwas fertig im Kopf von der letzten Nacht (Gartenpartys...^^), aber ich glaube du meintest .07/Juli^^

So, jezz mach ich mich mal übers Tut her, Design sieht schonmal sehr übersichtlich aus :)

so far

GimbaR


Narses - So 23.07.06 12:03

Moin!

Ja, hatte wohl beim Anpassen des Datums einen kleinen Zeitsprung in der Schüssel... :nut:

Hab´s jetzt korrigiert, auch im Tut selbst. ;)

cu
Narses


Narses - Fr 22.09.06 00:44

Moin!

Es gibt eine neue Version: V4.00-Milestone-Edition- vom 22.09.2006!

Es ist fast alles neu! ;) Da dieses Tutorial sich konkret an Anfänger in Sachen Netzwerk richtet, waren die Vorgängerversionen (leider :() schon mit viel zu viel Detailproblemen und deren ausufernden Lösungen vollgestopft. Das hatte natürlich den gegenteiligen Effekt, wie beabsichtigt: Abschreckung, statt leicher Einstieg. :D Deshalb wieder back-to-the-roots, nur das notwendigste in Kürze, aber mit Würze! ;) Also, wer bisher von den Vorgängerversionen eher abgeschreckt war, sollte nochmal reinschauen, das ganze Thema ist jetzt sehr viel einfacher präsentiert und garantiert einen weiteren Blick wert! :zwinker:

Für die schon etwas fortgeschritteneren Leser, die jetzt spezielle Themen (wie den Binärdatentransfer) vermissen: Es geht nichts aus den Vorgängerversionen verloren, ich werde die jetzt fehlenden Teile im zweiten Teil - ebenfalls in verbesserter Form - wieder präsentieren. Noch etwas Geduld, bitte. ;)

Details und Download - wie immer - im ersten Beitrag des Threads.

cu
Narses


Narses - Fr 13.10.06 14:01

Moin!

Der angekündigte, 2. Teil des Tutorials [http://www.delphi-library.de/topic_TerminatorzeichenProtokollTutorial++2+Sockets+v100_65487.html] ist jetzt fertig. ;)

Viel Erfolg damit. :D

cu
Narses


freddiiii - Di 24.10.06 08:43

Hervorangendes Tutorial :)
Hat bisher gut bei meinen Anfängerproblemen geholfen un wird auch nochn paar offene Fragen klären denk ich mal!
Einfach top..
Und hingegen vieler anderen Leute is Narses auch noch sehr hilfsbereit gegenüber Anfängern die weitergehende Fragen haben oder Tips brauchn :)

fred


-Pl- - Di 30.01.07 14:19

Da hammer den Thread ja .. ;-)

Einfach super Tutorial ! Habe jetzt auch nochmal die neue Version durchgelesen, frei nach dem Motto, doppelt hält besser und kann das Tutorial einfach nur weiterempfehlen. Vorallem für diejenigen unter euch die noch nicht so die Erfahrung mit Internet/LAN bei Delphi haben. Super Einführung und Erklärung und man kann selber immernoch sehr gut drauf aufbauen und sich neue Dinge dazu überlegen, nicht zuletzt durch die immer wieder eingefügten Denkanstöße in diese Richtung.

Nochmal vielen Dank Narses !


catweasel - Mi 16.05.07 15:43

Hi,

wow. Wirklich tolles tut...
Mir is nur auf die schnelle ein kleiner Typo aufgefallen....
Auf Seite 35 bei Punkt b heisst es : ... ist keiner als die eigene....
... muesste heissen ... "ist kleiner als die eigene".

also nix fuer ungut.. ;-)
Catweasel


Narses - Sa 19.05.07 22:39

Moin!

user profile iconcatweasel hat folgendes geschrieben:
wow. Wirklich tolles tut

Danke. :D

user profile iconcatweasel hat folgendes geschrieben:
ein kleiner Typo aufgefallen

Habe ich schon korrigiert, aber dafür lohnt (noch) kein Update; trotzdem Danke für den Hinweis. ;)

cu
Narses


Hendi48 - Do 21.06.07 20:57

kann man auch irgendwie den server in der Userliste anzeigen lassen? Also mein Server heißt nich system sondern ich kann einen namen eingeben (edit1). Wenn ich unter

Delphi-Quelltext
1:
Clients.AddItem(Socket.RemoteHost,Socket); // in die Liste                    


Delphi-Quelltext
1:
Clients.AddItem(edit1.text,Socket); // in die Liste                    

tu, bekomm ich ne access violation und im client kommt alles doppelt


Narses - Do 21.06.07 22:20

Moin!

user profile iconHendi48 hat folgendes geschrieben:
kann man auch irgendwie den server in der Userliste anzeigen lassen?

Grundsätzlich kann man eine ganze Menge machen, die Frage ist, wieviel Aufwand das ist. :zwinker: Aber um die Frage kurz zu beantworten: nein, das geht nicht so ohne weiteres. :| (jedenfalls nicht, ohne den Rahmen des Tutorials oder auch nur eines Beitrags hier zu sprengen)

Der Server ist eben kein Client und hat als solcher nix in der Client-Liste zu suchen; das ist bei anderen Chat-Systemen ja auch nicht anders, oder steht bei dir der ICQ-Server mit in der Kontaktliste... 8) :mahn:

user profile iconHendi48 hat folgendes geschrieben:
Also mein Server heißt nich system sondern ich kann einen namen eingeben (edit1). Wenn ich unter

Delphi-Quelltext
1:
Clients.AddItem(Socket.RemoteHost,Socket); // in die Liste                    


Delphi-Quelltext
1:
Clients.AddItem(edit1.text,Socket); // in die Liste                    

tu, bekomm ich ne access violation und im client kommt alles doppelt

Das ist ja auch "falsch" (Server ist kein Client und hat in der Liste nix zu suchen), deshalb gibt´s hier korrekterweise Fehlermeldungen. :?

cu
Narses


Hendi48 - Do 21.06.07 23:07

ok stimmt, jetz wo dus sagst :oops:
Egal dann geh ich eben auch als Client rein :wink:


jackle32 - Fr 17.08.07 23:54

Hallo erst mal,

ich hab mal ein ganz grundsätzliche Frage zu den Sockets. Worin besteht jetzt genau der Unterschied zwischen den T-Socket und den TCP-Socket? Würde der Chat auch laufen wenn ich jetzt einen TCP-Socket her nehm, den den gleichen Namen gebe (also z.B. "ClientSocket1")? Soll heißen sind die Befehle idtentisch oder anders und wenn sich die Sockets unterscheiden, wann nehm ich welchen für was? Zumal ich irgendwo gelesen hab, dass die T-Sockets von Borland als "bugy" eingestuft werden.

Hoffe ich bin im richten Thread und auf baldige Antwort

Gruß

Jack


Narses - Mo 20.08.07 00:12

Moin!

user profile iconjackle32 hat folgendes geschrieben:
Worin besteht jetzt genau der Unterschied zwischen den T-Socket und den TCP-Socket?

Es sind gänzlich unterschiedliche Komponenten, näheres verrät dir die Delphi-Online-Hilfe. :les: ;)

user profile iconjackle32 hat folgendes geschrieben:
Würde der Chat auch laufen wenn ich jetzt einen TCP-Socket her nehm

Nein (unter der Annahme, dass du für TClientSocket einen TTCPClient verwenden möchtest).

user profile iconjackle32 hat folgendes geschrieben:
wenn sich die Sockets unterscheiden, wann nehm ich welchen für was?

Das mußt du selbst entscheiden, indem du dir beide Komponenten mal intensiv anschaust; ich kann dir dabei leider nicht helfen. :?

user profile iconjackle32 hat folgendes geschrieben:
Zumal ich irgendwo gelesen hab, dass die T-Sockets von Borland als "bugy" eingestuft werden.

Die Socket-Kompos sind etwa genau so bugy, die andere WSA-API-Wrapper auch; man muss sie halt zu nehmen wissen. :) Sie sind zugegeben "veraltet" (was auch immer das nun genau bedeuten mag :nixweiss:) und bieten keine höhere (Standard-)Protokollunterstützung, wie z.B. die Indy-Komponenten. Zum Einstieg (also zum Lernen) sind diese Komponenten allerdings relativ gut geeignet, weil man eben alles selbst machen muss und so auch viel lernen kann. :idea:

Weitere (Grundsatz-)Fragen (zu den Komponenten) aber bitte im Forum stellen; das hier ist die Library und speziell der Thread zu einem ganz konkreten Tutorial - und da hat diese Diskussion eigentlich nix zu suchen (gab übrigens auch schon ein paar Threads zu diesem Thema, einfach mal suchen); ich habe auch nur deshalb (hier) darauf geantwortet, weil du nach einer Ersatzmöglichkeit zum Einsatz im Chat gefragt hast.

cu
Narses


PeterPain - Fr 30.11.07 00:13

Hi Narses!

Deine Tutorials sind ja mal mehr als genial. Auch wenn ich sie nicht benötige habe ich sie gerne gelesen und möchte gesagt haben, dass ein derartiges Engagement, und das auch noch für lau (oder bezahlt man dich dafür?) wirklich mehr als Vorbildich ist! Weiter so :)

Gaanz grosses Kino!

Viele grüsse, peter


Narses - Fr 30.11.07 00:32

Moin!

user profile iconPeterPain hat folgendes geschrieben:
Deine Tutorials sind ja mal mehr als genial.
Vielen Dank! :D

user profile iconPeterPain hat folgendes geschrieben:
oder bezahlt man dich dafür?
Das tut man zwar, aber nicht hierfür. :rofl: Ich habe die Tutorials natürlich nicht ausschließlich für´s Forum geschrieben, da gab´s auch noch andere Gründe... ;)

cu
Narses


morvister - Do 31.07.08 23:32
Titel: Meldung im Server-Protokoll: <NICK> hat sich angemeldet
Hallo Narses,

Ich bin relativ unbedarft was Delphi angeht, mit Programmierung an sich kenne ich mich aber aus, leider kaum mit der OOP. Soviel zu meinem Kenntnisstand. Ich interessiere mich für die Techniken, ein netzwerkfähiges Spiel mit relativ geringem Datentransfer zu erstellen und habe mich daher mit Freuden auf dieses wirklich hervorragende Tutorial gestürzt.

Die Chat-Anwendung läuft soweit und ich denke, ich habe das meiste im Großen und Ganzen verstanden. Lediglich das Zusammenspiel der TCmdToken- und der Syntax-Komponente bereiten mir noch etwas Probleme was das Verständnis angeht. Liegt vermutlich an mangelnder Kenntnis über Delphi und seiner Syntax.

Meine eigentliche Frage aber dreht sich um die Nicknamen. Ich wollte ein wenig herumprobieren und hatte die Idee, beim Verbinden eines Clients mit dem Server ins Protokoll des Servers so etwas wie "Neuer Client verbunden: <NICK>" auszugeben.
Meiner Meinung gehört das in die "OnClientConnect"-Methode der Server-Socket-Komponente.

Mein 1. Versuch war das hier:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
   Clients.AddItem(Socket.RemoteHost,Socket);                     //in die Liste
   ReceiveBuffer.Add('');                                         //zugehörigen Empfangspuffer anlegen
   Log.Lines.Add('Neuer Client verbunden: '+ Socket.RemoteHost);  //Meldung im Server-Protokoll
   SendUserList;
end;
Die Meldung wurde erzeugt, allerdings mit 'localhost' und nicht dem Nicknamen, wie ich es vermutet hatte. Eigentlich ist das auch sehr verständlich, aber ich frage mich, wie du es dann geschafft hast, mit dem 1. Befehl der Procedure den NICK in die Client-Liste einzutragen, wenn in Socket.RemoteHost 'localhost' steht, und nicht etwa der Nick.

Nach diesem Fehlschlag habe ich mich entschlossen, direkt auf die ListBox zu gehen.

Ein Versuch mit der Log.Lines.Add-Zeile wie oben, nur statt Socket.RemoteHost dann

Delphi-Quelltext
1:
Clients.Items.Strings[Clients.Items.Count-1]);                    


Ein weiterer Versuch mit Clients.Items.Strings[Clients.Items.IndexOfObject(Socket)]) statt Socket.Remote in derselben
Zeile.

Immer kommt dabei raus: "localhost"

Aber, wenn selbst in der Liste "localhost" statt des Nicknamens steht, wieso werden dann die Nicks angezeigt?

Mein Programm sieht exakt so aus, wie es gemäß Deines Tutorials aussehen müsste. Ich habe es inkl. des Änderns des Nicks mittels BtnSetNick erfolgreich durchgearbeitet. Da kam mir dann die Idee mit dieser Meldung.

Kannst Du mir helfen?

Sorrry der Quellcode ist etwas unübersichtlich. Ich bin neu hier und hab keine Ahnung, wie man die Quelltexte IDE-konform hier hinein bekommt.

Gruß
morvi

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


Narses - Do 31.07.08 23:55
Titel: Re: Meldung im Server-Protokoll: <NICK> hat sich angemeldet
Moin und :welcome: im Forum!

user profile iconmorvister hat folgendes geschrieben:
Meine eigentliche Frage aber dreht sich um die Nicknamen. Ich wollte ein wenig herumprobieren und hatte die Idee, beim Verbinden eines Clients mit dem Server ins Protokoll des Servers so etwas wie "Neuer Client verbunden: <NICK>" auszugeben.
Meiner Meinung gehört das in die "OnClientConnect"-Methode der Server-Socket-Komponente.
Grundsätzlich gehörte es wohl vielleicht da hinein, allerdings steht zu diesem Zeitpunkt der Nickname des neuen Clients ja noch gar nicht fest. :idea:

user profile iconmorvister hat folgendes geschrieben:
Mein 1. Versuch war das hier:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
   Clients.AddItem(Socket.RemoteHost,Socket);                     //in die Liste
   ReceiveBuffer.Add('');                                         //zugehörigen Empfangspuffer anlegen
   Log.Lines.Add('Neuer Client verbunden: '+ Socket.RemoteHost);  //Meldung im Server-Protokoll
   SendUserList;
end;
Die Meldung wurde erzeugt, allerdings mit 'localhost' und nicht dem Nicknamen
Zur Klärung: mit Socket.RemoteHost bekommst du den Hostnamen der Gegenstelle, wenn der Server und der Client auf der gleichen Maschine laufen, also korrekterweise 'localhost'.

user profile iconmorvister hat folgendes geschrieben:
ich frage mich, wie du es dann geschafft hast, mit dem 1. Befehl der Procedure den NICK in die Client-Liste einzutragen, wenn in Socket.RemoteHost 'localhost' steht, und nicht etwa der Nick.
Des Rätsels Lösung ist hier im Client-Code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
// Befehle ausführen; die notwendige Anzahl Argumente ist garantiert
procedure TForm1.Execute(const Command: TCmdToken; Data: TStringList);
  var
    i: Integer;
begin
  case Command of // Befehle fallunterscheiden:
    //...
    cmdVER: // Erweiterung 4: Protokoll-Version des Servers auswerten
      // ist das ein Narses-Chat-Server? (will ich mit dem reden?)
      if (Data.Strings[1] = SRV_APP_ID) then // ja
        // passende Protokoll-Version? (kann ich mit dem reden?)
        if (Data.Strings[2] = PROTO_VER) then begin // ja
          // der Server ist OK; im Log vermerken und Nickname senden
          Log.Lines.Add(Data.Strings[1]+', PV: '+Data.Strings[2]+'.'+Data.Strings[3]);
          ClientSocket1.Socket.SendText(Syntax[cmdNICK].Text+#13+Nickname.Text+#13);
Der Nickname wird als "Antwort" auf die Versionskennung des Servers gesendet (das Ganze ist Teil der Connect-Ereigniskette). :idea:

user profile iconmorvister hat folgendes geschrieben:
Immer kommt dabei raus: "localhost"
Ich denke, dir sollte jetzt klar werden, warum. ;)

user profile iconmorvister hat folgendes geschrieben:
Ich bin neu hier und hab keine Ahnung, wie man die Quelltexte IDE-konform hier hinein bekommt.
Markiere einfach den entsprechenden Abschnitt/Quelltext im Editor und klicke dann auf das '+'-Zeichen neben dem "Delphi" in der Combobox für den Syntaxhighlighter.

cu
Narses


morvister - Fr 01.08.08 00:49

Zunächst mal vielen Dank für die schnelle Antwort :-)

Ich habe die Protokoll-VersionsPrüfung bei mir noch gar nicht eingebaut. Ich habe das Tutorial erst bis 4.2 "ändern des Nicknamen im Betrieb" durchgearbeitet und auf dem Stand sieht die OnClientconnect-Prozedur (ohne meine Sonderlocke mit der Meldung übre neue Verbindung, daher auskommentiert quasi so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
   Clients.AddItem(Socket.RemoteHost,Socket);   //in die Liste
   ReceiveBuffer.Add(''); //zugehörigen Empfangspuffer anlegen
   // <- Hier wollte ich die Log.Lines.Add-Anweisung einbauen, wie folgt:
   //Log.Lines.Add('Neuer Client verbunden: '+
      Clients.Items.Strings[Clients.Items.Count-1]);

   SendUserList;   //User-Liste an alle Clients senden
end;


Ich bin nun aufgrund des Aufrufs von SendUserList am Ende der Procedure davon ausgegangen, dass die User-Liste zu diesem Zeitpunkt schon aktuell sein muss, und zwar durch Clients.AddItem(Socket.RemoteHost.Socket) sonst würds ja nix bringen, sie durch den Äther zu jagen :)

Ich hab sicher irgendwo nen Denkfehler oder ich habe die Reihenfolge der Ereignisse noch nicht aufm Schirm...Ich habs so verstanden, dass das OnConnect-Ereignis auf der Client-Seite, welches in meinem Fall so aussieht:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
//Verbindung zum Server ist aufgebaut und bereit zum Senden/Empfangen
procedure TForm1.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
   ReceiveBuffer := '';    //Empfangspuffer initialisieren
   ConnectionState := mcsOnline;   //Buttons anpassen
   Log.Clear;
   Log.Lines.Add('Verbunden mit: '+ClientSocket1.Socket.RemoteHost);
   Socket.SendText('NICK'+#13+Nickname.Text+#13); //noch den eigenen Nick senden
end;


das OnClientConnectEreignis auf der Server-Seite auslöst. Wenn dem so wäre, wäre die Info über den Nicknamen auf der Servcerseite vorhanden. Und vorhanden muss sie ja auch sein, wegen des Aufrufs von  SendUserList :gruebel:

Kannst Du mir helfen, den Knoten zu lösen?
Gruß
morvi


Narses - Fr 01.08.08 01:01

Moin!

user profile iconmorvister hat folgendes geschrieben:
Ich habe die Protokoll-VersionsPrüfung bei mir noch gar nicht eingebaut.
OK, ich hab einfach mal den letzten Code-Checkpoint genommen, weil du angedeutet hast, das Tut fertig zu haben. :nixweiss:

user profile iconmorvister hat folgendes geschrieben:
Ich bin nun aufgrund des Aufrufs von SendUserList am Ende der Procedure davon ausgegangen, dass die User-Liste zu diesem Zeitpunkt schon aktuell sein muss, und zwar durch Clients.AddItem(Socket.RemoteHost.Socket) sonst würds ja nix bringen, sie durch den Äther zu jagen
Nein, die Userliste enthält hier noch nicht den Nicknamen und nochmal nein, es bringt eine aktuelle Userliste, allerdings noch ohne den korrekten Nicknamen. ;)

user profile iconmorvister hat folgendes geschrieben:
ich habe die Reihenfolge der Ereignisse noch nicht aufm Schirm...
Wer auch immer welches Ereignis im TCP-Connecting triggert, der Nickname kommt auf jeden Fall erst im OnReceive rein und wird demzufolge im Execute-Ereignis verarbeitet. :idea:

cu
Narses


morvister - Fr 01.08.08 06:51

Moin

Danke, ich denke, diese Aussagen waren zum "Knoten lösen" geeignet :wink:

Und sorry für meine irreführenden Aussagen bzgl. des Stands Deines Tuts bei mir...es war wohl schon etwas zu spät :oops:

Besten Dank nochmal


Stinger47 - Do 20.08.09 14:07

Heyho,
auch von mir erstmal ein großes lob an das tut...für einen einsteiger wie mich in dieser matherie wirklich verständlich geschrieben...:)
aber irgendetwas will bei mir einfach nicht funktionieren :bawling:
habe das tut bis zu CC2 durchgearbeitet und soweit alles verstanden nochmal selber nachprogrammiert ohne pdf...
aber eins will einfach nicht
wenn ich mich mit dem client verbinde erscheinen in dem log nur chinesische! zeichen
beim text senden sowohl vom server als auch vom client kommt nur die fehlermeldung "unbekanntest kommando: [wieder chinesische zeichen]"
die userliste wird nicht aktualisiert wieder nur chinesische murks
bei den fertig kompilierten exe-dateien funktioniert es...
compiliere ich deinen code aber neu kommt dort der selbe fehler wie bei mir...
liegt es an meinem delphi?
habe letzten von einem bekannten delphi 2009 bekommen...
habe vista 64 bit
liegt es am delphi?..windows? :?!?:

Grüßle


BenBE - Do 20.08.09 14:11

Narses arbeitet mit AnsiStrings (in früheren Versionen String); seit D2009 wird für String standardmäßig WideString genommen. Änder alle Vorkommen von String nach AnsiString und probier das nochma ... Ansonsten mal kurzen Source online stellen.


Narses - Do 20.08.09 14:22

Moin!

user profile iconStinger47 hat folgendes geschrieben Zum zitierten Posting springen:
liegt es an meinem delphi?
habe letzten von einem bekannten delphi 2009 bekommen
Ja, es liegt an D2009.

user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Narses arbeitet mit AnsiStrings (in früheren Versionen String); seit D2009 wird für String standardmäßig WideString genommen. Änder alle Vorkommen von String nach AnsiString und probier das nochma
Das wird vermutlich leider nur teilweise helfen, da die Socket-Komponenten in D2009 bei .ReceiveText() bereits die empfangenen Daten ruinieren (intern wird der generische Typ String verwendet). Hier kommt man nur mit Ersetzen der .ReceiveText()-Aufrufe durch .ReceiveBuf() weiter, oder aber am besten nicht D2009 nehmen. Jede Version kleiner D2009, z.B. D7, wäre relativ gut hierfür geeignet. ;)

cu
Narses


BenBE - Do 20.08.09 14:25

Hi,

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Narses arbeitet mit AnsiStrings (in früheren Versionen String); seit D2009 wird für String standardmäßig WideString genommen. Änder alle Vorkommen von String nach AnsiString und probier das nochma
Das wird vermutlich leider nur teilweise helfen, da die Socket-Komponenten in D2009 bei .ReceiveText() bereits die empfangenen Daten ruinieren (intern wird der generische Typ String verwendet). Hier kommt man nur mit Ersetzen der .ReceiveText()-Aufrufe durch .ReceiveBuf() weiter, oder aber am besten nicht D2009 nehmen. Jede Version kleiner D2009, z.B. D7, wäre relativ gut hierfür geeignet. ;)

cu
Narses

Und jetzt sag nicht, dass du nicht bereits vor Jahren gewarnt wurdest, dass man Strings nicht zum Speichern von Binärdaten nimmt ...

:!: :toldyouso: :!:

MfG,
BenBE.

:mrgreen:


Stinger47 - Do 20.08.09 14:56

Hi,
erstmal danke für die schnellen antworten...
dann wirds wohl das einfachste sein eine ältere version zu nehmen :)

Grüßle