Delphi-Forum.de Delphi-Library.de
C-Sharp-Forum.de C-Sharp-Library.de
Registrieren Login Suche Hilfe Sitemap
Minimaler LAN/Internet-Chat mit TServer-/TClientSocket
spacer
Autor Nachricht
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

Beiträge: 7323
Erhaltene Danke: 7
Dabei seit: 25.07.2004
Wohnort: Gelsenkirchen

W2k, WXPpro
D6pe, D7pro
BeitragVerfasst: Mo 29.05.06 23:50  Antworten mit Zitat Beitrag melden
Narses´ Netzwerk-Tutorials - Navigation
  1. FAQ-Beitrag: Socket-Komponenten nachinstallieren (ab D7)
  2. hier :arrow: Netzwerk-Basics - Minimaler Chat für Anfänger
  3. Terminatorzeichen-Protokoll - Grundlagen
  4. Terminatorzeichen-Protokoll - Erweiterungen
  5. Binär-Protokoll - Für Fortgeschrittene
  6. Netzwerk-Spiel - Multiplayer TicTacToe
  7. UDP LAN-Chat - Der Chat ohne Server
Wie macht man einen LAN/Internet-Chat mit TServerSocket und TClientSocket?

Hier ist ein Anfänger-Tutorial für einen (wirklich minimalen) Netzwerk-Chat auf Basis der Socket-Komponenten (TServerSocket und TClientSocket). Falls die Sockets nicht in der Komponenten-Palette verfügbar sein sollten, ist im oben erwähnten FAQ-Beitrag eine ausführliche Anleitung zur Nachinstallation. Das Tutorial ist mit Delphi 7 Pro erstellt worden (ich sehe aber keine Probleme mit anderen Delphi-Versionen, solange die Socket-Komponenten installiert sind). In den Personal Editions von Delphi sind die Socket-Komponenten leider nicht in der IDE verfügbar, können aber trotzdem dynamisch verwendet werden. Mehr dazu ganz am Ende des Textes bei den Anhängen.

Wir werden für unseren Chat zwei Programme schreiben, einen Client, den die Chat-Teilnehmer verwenden werden und einen Server, der die Clients miteinander verbindet. Nochmal deutlich: nur einmal das Server-Programm starten und dann benutzt jeder einen Client, um am Chat teilzunehmen (auch der, der das Server-Programm gestartet hat!). ;) Die Clients verbinden sich dann mit dem einen Server-Programm (wie das genau geht, kommt gleich noch, bitte weiterlesen).

Zunächst das Server-Programm. Wir starten die IDE und legen ein neues Projekt an. Damit wir nicht ganz so viel an der Oberfläche herumbasteln müssen, hier das Formular in der Textdarstellung. Zum Übernehmen einfach das leere Formular anklicken, ALT+F12 drücken, dann wird in die Textdarstellung gewechselt. Jetzt den Text unten markieren, kopieren und dann den Inhalt im IDE-Fenster für das Formular komplett ersetzen (alles markieren und den kopierten Text von hier einfügen):
ausblenden volle Höhe Quelltext markieren
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:
object Form1: TForm1
Left = 226
Top = 121
Width = 209
Height = 132
Caption = 'Server'
Color = clBtnFace
Constraints.MinHeight = 132
Constraints.MinWidth = 209
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
Position = poDesktopCenter
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object Log: TMemo
Left = 8
Top = 8
Width = 185
Height = 89
Anchors = [akLeft, akTop, akRight, akBottom]
TabOrder = 0
end
object ServerSocket1: TServerSocket
Active = False
Port = 0
ServerType = stNonBlocking
OnClientRead = ServerSocket1ClientRead
Left = 88
Top = 40
end
end

Mit ALT+F12 schalten wir wieder in die grafische Darstellung des Formulars zurück. Jetzt können wir den Code übernehmen, dabei ersetzen wir den Standard-Quelltext in der IDE einfach komplett:
ausblenden volle Höhe Delphi-Quelltext markieren
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:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp;

const
MY_PORT = 12345; // an diesem Port melden sich die Clients

type
TForm1 = class(TForm)
Log: TMemo;
ServerSocket1: TServerSocket;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

// beim Programmstart ausführen
procedure TForm1.FormCreate(Sender: TObject);
begin
ServerSocket1.Port := MY_PORT; // den Port eintragen
ServerSocket1.Open; // Server aktivieren
Log.Lines.Add('Server online.');
end;

// beim Programmende ausführen
procedure TForm1.FormDestroy(Sender: TObject);
begin
ServerSocket1.Close; // Server deaktivieren
end;

// Daten von einem Client eingetroffen
procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
MyMessage: AnsiString;
i: Integer;
begin
// Nachricht lesen und davor die IP des Absenders setzen
MyMessage := Socket.RemoteAddress+': '+Socket.ReceiveText;
Log.Lines.Add(MyMessage); // Nachricht lokal ausgeben
// und an alle verbundenen Clients senden
for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
ServerSocket1.Socket.Connections[i].SendText(MyMessage);
end;

end.

Hier ein paar kurze Erläuterungen zum Quelltext:
Ganz am Anfang definieren wir eine Konstante für den Port, auf dem die Kommunikation stattfinden soll:
ausblenden Delphi-Quelltext markieren
1:
2:
const
MY_PORT = 12345; // an diesem Port melden sich die Clients

Einen Port kann man sich als virtuelle Steckdose an einem PC vorstellen. Damit ist es möglich, gleichzeitig mehrere Verbindungen über die gleiche IP-Adresse abzuwickeln. Dabei gilt es allerdings zu beachten, dass es bestimmte vordefinierte Ports gibt (sog. "well known ports"), die man nicht für eigene Anwendungen verwenden sollte. Dieser reservierte Bereich geht von 1-1024 (TCP). Fazit: Für eigene Anwendungen sollte man Portnummern oberhalb 1024, noch besser fünfstellige, verwenden.

Im FormCreate-Ereignis weisen wir den Port zu und aktivieren dann den Serverdienst. Ab jetzt können sich Clients mit dem Server verbinden. Dazu braucht der Client die IP-Adresse des PCs, auf dem der Server läuft und die Portnummer, an der der Server auf Clients wartet. Dazu später beim Client mehr.

Im FormDestroy-Ereignis schließen wir noch den Serverdienst, das Programm soll ja beendet werden. Dabei werden eventuell noch verbundene Clients zwangsgetrennt.

Bleibt nur noch das OnClientRead-Ereignis des Servers, dass wir uns jetzt ganz genau ansehen werden:
ausblenden Delphi-Quelltext markieren
1:
2:
// Daten von einem Client eingetroffen
procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);

Dieses Ereignis tritt ein, wenn eine Verbindung zu einem Client Daten empfangen, oder anders gesagt, wenn ein Client Daten gesendet hat. Dabei wird in Sender die Komponente geliefert, die das Ereignis ausgelöst hat (hier: ServerSocket1) und in Socket die Verbindung, die Daten empfangen hat (hier: ein Element des ServerSocket1.Socket.Connections[]-Array).
ausblenden Delphi-Quelltext markieren
1:
2:
  // Nachricht lesen und davor die IP des Absenders setzen
MyMessage := Socket.RemoteAddress+': '+Socket.ReceiveText;

Wir bauen uns hier aus Socket.RemoteAddress, das die IP-Adresse des Clients enthält, und aus Socket.ReceiveText, was die gesendeten Daten liefert, ein eigenes Nachrichtenformat zusammen. Auf diese Weise können wir die Nachrichten wenigstens grob unterscheiden. Warum nehmen wir keine Nicknames? Das geht zwar theoretisch, allerdings wird es an dieser Stelle schon schwer, ohne ein Protokoll auszukommen. Wir wollen den Rahmen dieses Tutorial nicht sprengen und verzichten deshalb auf Nicknames. Wer an dieser Stelle mehr wissen möchte, sollte mal hier nachsehen. ;)
ausblenden Delphi-Quelltext markieren
1:
  Log.Lines.Add(MyMessage); // Nachricht lokal ausgeben

Damit schreiben wir die Nachricht in das Protokoll-Fenster des Servers.

ausblenden Delphi-Quelltext markieren
1:
2:
3:
  // und an alle verbundenen Clients senden
for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
ServerSocket1.Socket.Connections[i].SendText(MyMessage);

Das sind eigentlich die entscheidenden Zeilen des Server-Codes: Die Schleife läuft über die Anzahl der aktuell verbundenen Clients (startet mit 0, deshalb -1 am Ende) und sendet an jede Verbindung den empfangenen Text (IP+Nachricht). Auf diese Weise erhalten alle Clients den gesendeten Text, der nur von einem Client kam.

Jetzt zum Client. Wir starten eine weitere IDE und legen ein neues Projekt an (wir wollen ja auch zwei Programme schreiben). Hier die Formulardaten in Textform, wie beim Server einfach mit ALT+F12 ersetzen:
ausblenden volle Höhe Quelltext markieren
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:
object Form1: TForm1
Left = 212
Top = 118
Width = 227
Height = 235
Caption = 'Client'
Color = clBtnFace
Constraints.MinHeight = 235
Constraints.MinWidth = 227
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
Position = poDesktopCenter
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 8
Top = 8
Width = 71
Height = 13
Caption = 'Serveradresse:'
end
object Label2: TLabel
Left = 8
Top = 48
Width = 41
Height = 13
Caption = 'Protokoll'
end
object Label3: TLabel
Left = 8
Top = 160
Width = 111
Height = 13
Anchors = [akLeft, akBottom]
Caption = 'Nachricht zum Senden:'
end
object ServerAdress: TEdit
Left = 8
Top = 24
Width = 121
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 0
Text = 'localhost'
end
object BtnSend: TButton
Left = 136
Top = 174
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Caption = '&Senden'
TabOrder = 1
OnClick = BtnSendClick
end
object Log: TMemo
Left = 8
Top = 64
Width = 201
Height = 89
Anchors = [akLeft, akTop, akRight, akBottom]
TabOrder = 2
end
object Online: TCheckBox
Left = 136
Top = 26
Width = 73
Height = 17
Anchors = [akTop, akRight]
Caption = '&Online'
TabOrder = 3
OnClick = OnlineClick
end
object Input: TEdit
Left = 8
Top = 176
Width = 121
Height = 21
Anchors = [akLeft, akRight, akBottom]
TabOrder = 4
Text = 'Hallo'
end
object ClientSocket1: TClientSocket
Active = False
ClientType = ctNonBlocking
Port = 0
OnConnect = ClientSocket1Connect
OnDisconnect = ClientSocket1Disconnect
OnRead = ClientSocket1Read
OnError = ClientSocket1Error
Left = 96
Top = 96
end
end

Hier der Quelltext, ebenfalls einfach den Standard-Code in der IDE komplett ersetzen:
ausblenden volle Höhe Delphi-Quelltext markieren
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:
unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp, StdCtrls;

const
MY_PORT = 12345; // an diesem Port wartet der Server auf Clients

type
TForm1 = class(TForm)
ServerAdress: TEdit;
Online: TCheckBox;
Log: TMemo;
Input: TEdit;
BtnSend: TButton;
ClientSocket1: TClientSocket;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure FormCreate(Sender: TObject);
procedure OnlineClick(Sender: TObject);
procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure BtnSendClick(Sender: TObject);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure FormDestroy(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

// bei Programmstart ausführen
procedure TForm1.FormCreate(Sender: TObject);
begin
ClientSocket1.Port := MY_PORT; // Port eintragen
end;

// Online-Checkbox wechselt den Status
procedure TForm1.OnlineClick(Sender: TObject);
begin
if (Online.Checked) then // falls wir online gehen...
ClientSocket1.Host := ServerAdress.Text; // ...Serveradresse eintragen
ClientSocket1.Active := Online.Checked; // neuen Status setzen
end;

// Verbindung erfolgt (connect) -> Meldung machen
procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
begin
Log.Lines.Add('Verbunden mit '+ServerAdress.Text);
end;

// Verbindung getrennt (disconnect) -> Meldung machen
procedure TForm1.ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
Log.Lines.Add('Verbindung getrennt.');
// falls der Server getrennt hat, sonst bleibt der Haken stehen,
Online.Checked := FALSE; // obwohl wir gar nicht mehr online sind!
end;

// Fehler in der Verbindung aufgetreten
procedure TForm1.ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
Log.Lines.Add('Fehler '+IntToStr(ErrorCode));
Online.Checked := FALSE; // sicherheitshalber Verbindung trennen
ErrorCode := 0; // keine Exception erzeugen, Fehler behandelt
end;

// Sende-Button bearbeiten
procedure TForm1.BtnSendClick(Sender: TObject);
begin
if (ClientSocket1.Active) then // sind wir online?
ClientSocket1.Socket.SendText(Input.Text) // ja, Text senden
else
Log.Lines.Add('Nicht verbunden!'); // nein, Meldung machen
end;

// Daten vom Server eingetroffen
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
Log.Lines.Add(Socket.ReceiveText); // lesen und ausgeben
end;

// bei Programmende ausführen
procedure TForm1.FormDestroy(Sender: TObject);
begin
if (ClientSocket1.Active) then // noch online?
ClientSocket1.Close; // ja, dann trennen
end;

end.

Erläuterungen zum Code (die konstante Portdefinition kennen wir jetzt schon):

Beim Programmstart tragen wir zunächst nur die Portnummer ein. Die Adresse des Servers brauchen wir erst dann, wenn wir eine Verbindung herstellen wollen. Dazu ist die CheckBox "Online" da, deren OnClick-Ereignis entsprechende Aktionen durchführt:
ausblenden Delphi-Quelltext markieren
1:
2:
3:
4:
5:
6:
7:
8:
9:
// Online-Checkbox wechselt den Status
procedure TForm1.OnlineClick(Sender: TObject);

begin
if (Online.Checked) then // falls wir online gehen...

ClientSocket1.Host := ServerAdress.Text; // ...Serveradresse eintragen
ClientSocket1.Active := Online.Checked; // neuen Status setzen
end;

Wenn wir von offline->online wechseln (das fragt die if-Bedingung ab), tragen wir vorher noch die Adresse des Servers ein. Dann weisen wir einfach den Zustand der CheckBox an die .Active-Eigenschaft des ClientSockets zu, so dass entweder eine Verbindung aufgebaut (Haken gesetzt) oder die Verbindung getrennt wird (Haken entfernt).

Wir gehen in unserem Beispiel mal davon aus, dass das Projekt nur auf dem lokalen PC getestet wird. Die eigene IP-Adresse ist immer "127.0.0.1" oder "localhost". Diese (virtuelle) Netzwerkschnittstelle ist auf jedem PC vorhanden und bezeichnet einfach "sich selbst". Deshalb ist "localhost" bereits voreingestellt, damit auch Benutzer ohne LAN das Tutorial auf dem eigenen PC nachvollziehen können. Das Projekt läuft selbstverständlich im LAN (dann die entsprechenden lokalen IP-Adressen verwenden) und ist durchaus auch über das Internet nutzbar. Allerdings braucht man hier dann die öffentliche IP-Adresse des PCs, auf dem das Server-Programm läuft. Diese lässt sich z.B. leicht in einem Browser über die Seite www.whatismyip.com abfragen. Vorsicht Falle: Wenn ein (DSL-)Router im Einsatz ist, dann ist noch ein Portforwarding (heißt auch manchmal "virtual Server") notwendig, sonst können sich Clients aus dem Internet nicht zum Server verbinden. Genaueres kann ich hier nicht allgemeingültig beschreiben, bitte gegebenenfalls im Forum nachfragen bzw. die Suchfunktion benutzen. ;) Nochmal Falle: Wird ein Client auf dem selben PC wie der Server gestartet, bleibt es für diesen Client weiterhin bei "localhost" als Serveradresse (ist ja auch auf dem selben PC)! Nur Clients, die von ausserhalb des LANs eine Verbindung aufbauen wollen, brauchen die öffentliche IP des Routers.

Wenn eine Verbindung aufgebaut werden konnte, tritt das Ereignis OnConnect ein, in dem wir die Verbindung melden.

Wird die Verbindung getrennt, tritt das Ereignis OnDisconnect ein. Auch hier melden wir Entsprechendes, allerdings setzen wir noch zusätzlich die CheckBox zurück, da - falls der Server die Verbindung getrennt hat - der Haken sonst stehen bleiben würde.

Konnte keine Verbindung zum Server hergestellt werden oder tritt in einer Verbindung ein Fehler auf, wird das Ereignis OnError ausgelöst. Wir protokollieren einfach den Fehler mit Nummer, trennen sicherheitshalber die Verbindung (falls das nicht schon geschehen sein sollte -> Haken-Problem) und setzen die Fehlervariable zurück, damit keine Exception ausgelöst wird.

Kommen wir jetzt aber endlich zu den interessanten Prozeduren: Wenn wir einen Text eingegeben haben und diesen nun senden wollen, müssen wir im Button-Ereignishandler nur noch den Text senden:
ausblenden Delphi-Quelltext markieren
1:
2:
3:
4:
5:
6:
7:
8:
// Sende-Button bearbeiten
procedure TForm1.BtnSendClick(Sender: TObject);
begin
if (ClientSocket1.Active) then // sind wir online?
ClientSocket1.Socket.SendText(Input.Text) // ja, Text senden
else
Log.Lines.Add('Nicht verbunden!'); // nein, Meldung machen
end;

Aber nur dann, wenn auch eine Verbindung besteht (-> if-Abfrage). Haben wir keine Verbindung, gibts nur eine Fehlermeldung, die wir statt dessen ins Protokoll schreiben.

Wenn wir die Textnachricht gesendet haben, erscheint allerdings noch nichts in unserem Protokoll. Das passiert erst dann, wenn der Server die Daten verarbeitet und uns eine entsprechende Nachricht zurückgesendet hat. In diesem Fall tritt das Ereignis OnRead ein, in dem wir die Daten vom Server lesen und ins Protokoll schreiben:
ausblenden Delphi-Quelltext markieren
1:
2:
3:
4:
5:
// Daten vom Server eingetroffen
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
Log.Lines.Add(Socket.ReceiveText); // lesen und ausgeben
end;

Kurz zusammengefasst: Text eintippen -> wird an den Server gesendet -> dieser verteilt die Nachricht an alle Clients -> Nachricht vom Server trifft ein -> ins Protokoll schreiben.

Dieses Konzept nennt man auch Client-Server-Architektur.

Beim Programmende wird natürlich noch eine eventuell bestehende Verbindung getrennt, wir beenden unsere Programme schließlich sauber. ;)

Wer mit diesem Tutorial erfolgreich den Einstieg ins "Netzwerken" geschafft hat und jetzt schon gespannt auf MEHR ist, sollte sich mal das Terminatorzeichen-Protokoll-Tutorial ansehen. Da werden sie geholfen. ;)

cu
Narses


Hinweis zu Delphi-Versionen >=D2009 (Unicode-Problem):
Der Code ist Unicode-Save, es sollte keine Probleme mit Delphi-Versionen >=D2009 geben.

Hinweis zu den Anhängen:
In der Personal-Edition von Delphi stehen die Socket-Komponenten leider nicht in der IDE zur Verfügung (dclsockets70.bpl wird nicht mitgeliefert). Allerdings ist die ScktComp.dcu ja auch bei der Personal-Edition vorhanden, so dass trotzdem (ganz legal!) mit den Socket-Komponenten gearbeitet werden kann, wenn man diese dynamisch erzeugt.
Da die Frage aufgekommen ist, wie man das denn konkret macht, gibt es zur Demonstration der Vorgehensweise die beiden Programme jetzt auch in einer Version, in der der TClientSocket und der TServerSocket dynamisch erzeugt werden.
Einloggen, um Attachments anzusehen!
_________________
There are 10 types of people - those who understand binary and those who don´t.


Zuletzt bearbeitet von Narses am So 21.02.10 01:47, insgesamt 24-mal bearbeitet
Private Nachricht sendenPosting in privater Nachricht zitieren
dac424
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star

Beiträge: 50
Dabei seit: 18.12.2004



BeitragVerfasst: Mo 10.07.06 22:23 
Titel: Geile Sache
Antworten mit Zitat Beitrag melden
wie sieht es mit Räume aus die Man erstellen könnte das wäre doch auch nicht übel
Private Nachricht sendenPosting in privater Nachricht zitieren
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

(Threadstarter)

Beiträge: 7323
Erhaltene Danke: 7
Dabei seit: 25.07.2004
Wohnort: Gelsenkirchen

W2k, WXPpro
D6pe, D7pro
BeitragVerfasst: Mo 10.07.06 22:29  Antworten mit Zitat Beitrag melden
Moin!

Ja, das kann man machen. ;) Dazu brauchst du aber schon ein Protokoll, deshalb solltest du dem entsprechenden Hinweis folgen und dir mal ansehen, wie man sowas umsetzt. Damit dann verschiedene Chat-Räume abzubilden, ist nicht weiter schwer.

Hier in diesem (Super-Simpel-)Beispiel führt das allerdings viel zu weit und hilft nicht beim Verständnis der grundlegenden Probleme.

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Private Nachricht sendenPosting in privater Nachricht zitieren
dac424
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star

Beiträge: 50
Dabei seit: 18.12.2004



BeitragVerfasst: Di 11.07.06 00:34 
Titel: Flüstern wäre das
Antworten mit Zitat Beitrag melden
Frage ist es den auch machbar zu flüstern an eine gewisse IP das nur Der Jenige das lesen kann und ev. noch Räume zu erstellen. Das wäre dann genau das PRG was ich bräuchte habe es im moment so wie es ist in meinem Projekt Implementiert und es läuft herfor- ragend.
Private Nachricht sendenPosting in privater Nachricht zitieren
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

(Threadstarter)

Beiträge: 7323
Erhaltene Danke: 7
Dabei seit: 25.07.2004
Wohnort: Gelsenkirchen

W2k, WXPpro
D6pe, D7pro
BeitragVerfasst: Di 11.07.06 01:09 
Titel: Re: Flüstern wäre das
Antworten mit Zitat Beitrag melden
Moin!

dac424 hat folgendes geschrieben:
Frage ist es den auch machbar zu flüstern an eine gewisse IP das nur Der Jenige das lesen kann

Ja, das ist bereits im Protokoll-Chat-Tutorial enthalten.

dac424 hat folgendes geschrieben:
und ev. noch Räume zu erstellen.

Ein Chat-Raum ist doch nix anderes, als eine virtuelle Gruppierung; läßt sich mit einem Protokoll ganz leicht umsetzen. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Private Nachricht sendenPosting in privater Nachricht zitieren
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

(Threadstarter)

Beiträge: 7323
Erhaltene Danke: 7
Dabei seit: 25.07.2004
Wohnort: Gelsenkirchen

W2k, WXPpro
D6pe, D7pro
BeitragVerfasst: Do 13.07.06 00:40  Antworten mit Zitat Beitrag melden
Moin!

Da die Frage danach aufkam: es gibt die Beispielprogramme jetzt auch in einer Version, bei der die Socket-Komponenten dynamisch erzeugt werden, so dass die Integration der Komponenten in der IDE nicht notwendig ist (Personal-Editions).

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Private Nachricht sendenPosting in privater Nachricht zitieren
pupu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star

Beiträge: 104
Dabei seit: 15.12.2005
Wohnort: Daverden

WinXP
Borland Delphi 7, Turbo Pascal 7
BeitragVerfasst: Do 13.07.06 14:36  Antworten mit Zitat Beitrag melden
wenn ich den server starte und dann mit dem client mich unter "localhost" verbinde, und dann das "hallo" abschick, denn dauert das erst ne weile und dann kommt ne Fehlermeldung mit dem Inhalt:

List index out of bounds (1)

hab ich was falsch gemacht? :?

der "chat" funktioniert ja quasi auch über netzwerk, nur dass der der sich verbinden will unter Adresse meine IP eingibt, weil bei mir der Server liegt oder irre ich mich da?
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

(Threadstarter)

Beiträge: 7323
Erhaltene Danke: 7
Dabei seit: 25.07.2004
Wohnort: Gelsenkirchen

W2k, WXPpro
D6pe, D7pro
BeitragVerfasst: Do 13.07.06 15:08  Antworten mit Zitat Beitrag melden
Moin!

pupu hat folgendes geschrieben:
wenn ich den server starte und dann mit dem client mich unter "localhost" verbinde, und dann das "hallo" abschick, denn dauert das erst ne weile und dann kommt ne Fehlermeldung mit dem Inhalt:
ausblenden Quelltext markieren
1:
List index out of bounds (1)

hab ich was falsch gemacht? :?

Kommt der Fehler bei meinen fertigen EXEcutables oder bei der von dir erstellten Version davon? Wenn ich das mit den EXEs probiere, klapp´s bei mir einwandfrei (bei anderen auch).

Wenn es mit meinen Programmen geht, aber mit deiner Version davon nicht, dann solltest du mal den Quelltext zeigen, weil sonst kommen wir nicht weiter. ;)

pupu hat folgendes geschrieben:
der "chat" funktioniert ja quasi auch über netzwerk, nur dass der der sich verbinden will unter Adresse meine IP eingibt, weil bei mir der Server liegt oder irre ich mich da?

Ich unterstelle mal, du meinst mit "Netzwerk" eine Internetverbindung. ;) Ja, das ist korrekt; wie aber weiter oben im Tutorial-Text schon erwähnt, ist bei einem Router für den Serverdienst noch ein Portforwarding notwendig.

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Private Nachricht sendenPosting in privater Nachricht zitieren
dac424
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star

Beiträge: 50
Dabei seit: 18.12.2004



BeitragVerfasst: Fr 14.07.06 09:25 
Titel: Flüstern und Chaträume
Antworten mit Zitat Beitrag melden
wäre nicht schlecht wenn man die version mit flustern und Räume haben könnte als source
würde mich über PN freuen, wo die Source bei ist.
Private Nachricht sendenPosting in privater Nachricht zitieren
dac424
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star

Beiträge: 50
Dabei seit: 18.12.2004



BeitragVerfasst: Fr 14.07.06 09:32 
Titel: Internet
Antworten mit Zitat Beitrag melden
also bei mir läuft die einband frei im Internet man solte jedoch den Port ändern 12345 ist nicht so optimal ich habe 6786 gemacht und dem entsprechen im Router frei gegeben zu dem rechner wo der Server läuft
es wäre auch nicht schlecht eine Art bann funktion wo man IP´s bzw eine funktion ausbauen könnte das man jemanden sperren kann sprich jeder client hat eine nummer
die man im server sperren kan.

Client instaliert 1 Start client vbekommt eine nummer die immer gleich bleibt.
Private Nachricht sendenPosting in privater Nachricht zitieren
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

(Threadstarter)

Beiträge: 7323
Erhaltene Danke: 7
Dabei seit: 25.07.2004
Wohnort: Gelsenkirchen

W2k, WXPpro
D6pe, D7pro
BeitragVerfasst: Fr 14.07.06 10:17  Antworten mit Zitat Beitrag melden
Moin!

Mein lieber dac424, das hier ist die super-simpel-Version für Einsteiger. ;)

Es macht einfach keinen Sinn, hier noch weitere Funktionen reinzustopfen, noch dazu, wenn dafür ein Protokoll notwendig ist. Ich habe dir weiter oben bereits einen Hinweis auf mein Protokoll-Chat-Tutorial gegeben, da wird auch lang und breit erklärt, wie man eine Flüstern-Funktion umsetzt. Chat-Räume sind eine weitere, mögliche Erweiterung, die du leicht selbst umsetzen kannst, wenn du erstmal den Grundgedanken eines Protokolls verstanden hast.

Bitte also hier nicht weiter nach neuen Funktionen fragen, da ich das an dieser Stelle nicht umsetzen werde, um den Charakter dieses Tutorials ("für Einsteiger") nicht kaputt zu machen.

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Private Nachricht sendenPosting in privater Nachricht zitieren
pupu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star

Beiträge: 104
Dabei seit: 15.12.2005
Wohnort: Daverden

WinXP
Borland Delphi 7, Turbo Pascal 7
BeitragVerfasst: Sa 15.07.06 11:50  Antworten mit Zitat Beitrag melden
ne ich meinte netzwerk...wenn ich z.b. mit meinem bruder nebenan chatten will oder so
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

(Threadstarter)

Beiträge: 7323
Erhaltene Danke: 7
Dabei seit: 25.07.2004
Wohnort: Gelsenkirchen

W2k, WXPpro
D6pe, D7pro
BeitragVerfasst: Sa 15.07.06 23:24  Antworten mit Zitat Beitrag melden
Moin!

pupu hat folgendes geschrieben:
ne ich meinte netzwerk...wenn ich z.b. mit meinem bruder nebenan chatten will oder so

Ja, klar geht das. ;)

Was ist nun mit deinem Laufzeitproblem? Gefunden?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Private Nachricht sendenPosting in privater Nachricht zitieren
dac424
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star

Beiträge: 50
Dabei seit: 18.12.2004



BeitragVerfasst: So 16.07.06 00:47 
Titel: also wenn ich das Richtig verstanden habe.
Antworten mit Zitat Beitrag melden
Versuche mir das jetzt mal bildlich um zusetzen
dann entscheidet der Server jetzt was an die Clients gesendet wird ?
ausblenden Delphi-Quelltext markieren
1:
MyMessage := Socket.RemoteAddress+': '+Socket.ReceiveText; //original


ich köntte doch den String erweitern oder??

ausblenden Delphi-Quelltext markieren
1:
MyMessage := Socket.RemoteAddress+': '+Socket.ReceiveText+Raum+Sperrung;


sollte jetzt die IP im Server eingetragen sein beispielsweise in einer Memo dann

könnte ich das Auswerten und bei dem Client eine unsichtbare checkbox aktivieren?

und wenn ich das Programm beende wird diese in der Registri eingetragen so wie ich auch die Serverdarten Eintrage!

starte ich das Program erneut ist die Checkbox immer noch gesetzt und der Client ist gesperrt, er bekommt zwar daten aber diese werden nicht in der Logausgabe gezeigt?

Moderiert von jasocul: Delphi-Tags hinzugefügt
Private Nachricht sendenPosting in privater Nachricht zitieren
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

(Threadstarter)

Beiträge: 7323
Erhaltene Danke: 7
Dabei seit: 25.07.2004
Wohnort: Gelsenkirchen

W2k, WXPpro
D6pe, D7pro
BeitragVerfasst: So 16.07.06 00:57  Antworten mit Zitat Beitrag melden
Narses hat folgendes geschrieben:
Mein lieber dac424, das hier ist die super-simpel-Version für Einsteiger. ;)

Es macht einfach keinen Sinn, hier noch weitere Funktionen reinzustopfen, noch dazu, wenn dafür ein Protokoll notwendig ist. Ich habe dir weiter oben bereits einen Hinweis auf mein Protokoll-Chat-Tutorial gegeben


Narses hat folgendes geschrieben:
Bitte also hier nicht weiter nach neuen Funktionen fragen, da ich das an dieser Stelle nicht umsetzen werde


Wenn du Kenntnis des Protokoll-Chats zeigst und im entsprechenden Thread fragst, würde ich mir überlegen, ob ich dir dann dabei weiterhelfe.

Hier passiert in dieser Richtung jedenfalls nix.

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Private Nachricht sendenPosting in privater Nachricht zitieren
pupu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star

Beiträge: 104
Dabei seit: 15.12.2005
Wohnort: Daverden

WinXP
Borland Delphi 7, Turbo Pascal 7
BeitragVerfasst: So 16.07.06 19:34  Antworten mit Zitat Beitrag melden
hier ma n screenshot, damit ihr euch das vielleicht etwas besser vorstellen könnt was genau passiert...vllt hilft das ja :wink:

Moderiert von Tino: Bild als Dateianhang hochgeladen.

edit: habs so weit gelöst...aus irgendeinem Grund hatte ich aus:
ausblenden Delphi-Quelltext markieren
1:
2:
3:
// und an alle verbundenen Clients senden
  for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
    ServerSocket1.Socket.Connections[i].SendText(MyMessage);

ein:
ausblenden Delphi-Quelltext markieren
1:
2:
3:
 // und an alle verbundenen Clients senden
  for i := 1 to ServerSocket1.Socket.ActiveConnections do
    ServerSocket1.Socket.Connections[i].SendText(MyMessage);


gemacht...wahrscheinlich zur Verständlichkeit :wink:
Einloggen, um Attachments anzusehen!
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

(Threadstarter)

Beiträge: 7323
Erhaltene Danke: 7
Dabei seit: 25.07.2004
Wohnort: Gelsenkirchen

W2k, WXPpro
D6pe, D7pro
BeitragVerfasst: Mi 13.09.06 17:17  Antworten mit Zitat Beitrag melden
Moin!

Es gibt jetzt auch eine Offline-Version des Tutorials als PDF im Anhang zum Download (wie immer, im ersten Beitrag). ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Private Nachricht sendenPosting in privater Nachricht zitieren
Memorius
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star

Beiträge: 25
Dabei seit: 02.06.2007
Wohnort: Breisch, Oberrimsingen

Windows XP Professional
Delphi 4.0 PE
BeitragVerfasst: Sa 02.06.07 23:05  Antworten mit Zitat Beitrag melden
Hallo!
Ich wollte mal fragen, ob es geht dass uch die IP-Adresse eines Servers auch übers Internet herausfinden kann, ohne bei dem, der den Server laufen hat anrufen zu müssen? Also, wenn viele Leute das Programm (oder besser: beide Programme) hat und eder nach belieben einen Server öffnen kann, geht es dann dass man diese Server im I-Net suchen und sich anzeigen lassen kann?
(ich hoffe diese frage wurde noch nicht beantwortet und ich habe sie einlicherweise übersehehn :?!?: )
ich weiß, das geht auch über das Mini-tutorial hinaus... aber BITTE!!!!! :flehan:

-Memorius-
Private Nachricht sendenPosting in privater Nachricht zitieren
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

(Threadstarter)

Beiträge: 7323
Erhaltene Danke: 7
Dabei seit: 25.07.2004
Wohnort: Gelsenkirchen

W2k, WXPpro
D6pe, D7pro
BeitragVerfasst: So 03.06.07 14:35  Antworten mit Zitat Beitrag melden
Moin!

Memorius hat folgendes geschrieben:
Ich wollte mal fragen, ob es geht dass uch die IP-Adresse eines Servers auch übers Internet herausfinden kann, ohne bei dem, der den Server laufen hat anrufen zu müssen?

Ja, klar geht das (s.u., allerdings evtl. nicht so, wie du möchtest). ;)

Memorius hat folgendes geschrieben:
Also, wenn viele Leute das Programm (oder besser: beide Programme) hat und eder nach belieben einen Server öffnen kann, geht es dann dass man diese Server im I-Net suchen und sich anzeigen lassen kann?

Nein, sowas geht nur, wenn ein fester Server im Internet die Vermittlung übernimmt. :?

Aber du kannst deinem PC einen dynamischen DNS-Alias verpassen, dann kann man diesen über den Namen (z.B. MyPC.dyndns.org) ansprechen, ohne die IP-Adresse zu kennen. :idea: ;)

Einfach mal hier ein bischen nach Suche in: Delphi-Forum.de DYNDNS suchen, dann auf der DynDNS-Homepage registrieren (www.dyndns.org, 5 Hosts sind für private Anwendung kostenlos) und loslegen. :D

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Private Nachricht sendenPosting in privater Nachricht zitieren
Memorius
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star

Beiträge: 25
Dabei seit: 02.06.2007
Wohnort: Breisch, Oberrimsingen

Windows XP Professional
Delphi 4.0 PE
BeitragVerfasst: So 03.06.07 15:16  Antworten mit Zitat Beitrag melden
Danke!!!
Private Nachricht sendenPosting in privater Nachricht zitieren
Werbung ausblenden? Dann registriere Dich kostenlos. Weitere Gründe für eine Registrierung.


Werbung ausblenden? Dann registriere Dich kostenlos. Weitere Gründe für eine Registrierung.
Beiträge vom vorherigen Thema anzeigen:   
home home