Entwickler-Ecke

Delphi Tutorials - Minimaler LAN/Internet-Chat mit TServer-/TClientSocket


Narses - Mo 29.05.06 23:50
Titel: Minimaler LAN/Internet-Chat mit TServer-/TClientSocket
Narses´ Netzwerk-Tutorials - Navigation
  1. FAQ-Beitrag: Socket-Komponenten nachinstallieren (ab D7) [http://www.delphi-library.de/topic_64438.html]
  2. hier :arrow: Netzwerk-Basics - Minimaler Chat für Anfänger
  3. Terminatorzeichen-Protokoll - Grundlagen [http://www.delphi-library.de/topic_54269.html]
  4. Terminatorzeichen-Protokoll - Erweiterungen [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]
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):

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
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:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
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:

Delphi-Quelltext
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:

Delphi-Quelltext
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).

Delphi-Quelltext
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 [http://www.delphi-library.de/topic_TerminatorzeichenProtokollTutorial_54269.html] nachsehen. ;)

Delphi-Quelltext
1:
  Log.Lines.Add(MyMessage); // Nachricht lokal ausgeben                    

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


Delphi-Quelltext
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:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
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:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
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:

Delphi-Quelltext
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 http://www.whatismyip.com abfragen. Vorsicht Falle: Wenn ein (DSL-)Router im Einsatz ist, dann ist noch ein Portforwarding [http://www.delphi-library.de/topic_Portforwarding++Eine+kleine+Einfuehrung_80904.html] (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:

Delphi-Quelltext
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:

Delphi-Quelltext
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 [http://www.delphi-library.de/topic_TerminatorzeichenProtokollTutorial_54269.html] 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.


dac424 - Mo 10.07.06 22:23
Titel: Geile Sache
wie sieht es mit Räume aus die Man erstellen könnte das wäre doch auch nicht übel


Narses - Mo 10.07.06 22:29

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


dac424 - Di 11.07.06 00:34
Titel: Flüstern wäre das
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.


Narses - Di 11.07.06 01:09
Titel: Re: Flüstern wäre das
Moin!

user profile icondac424 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.

user profile icondac424 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


Narses - Do 13.07.06 00:40

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


pupu - Do 13.07.06 14:36

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?


Narses - Do 13.07.06 15:08

Moin!

user profile iconpupu 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:

Quelltext
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. ;)

user profile iconpupu 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


dac424 - Fr 14.07.06 09:25
Titel: Flüstern und Chaträume
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.


dac424 - Fr 14.07.06 09:32
Titel: Internet
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.


Narses - Fr 14.07.06 10:17

Moin!

Mein lieber user profile icondac424, 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 [http://www.delphi-library.de/topic_ProtokollChatTutorial+V300_54269.html] 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


pupu - Sa 15.07.06 11:50

ne ich meinte netzwerk...wenn ich z.b. mit meinem bruder nebenan chatten will oder so


Narses - Sa 15.07.06 23:24

Moin!

user profile iconpupu 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


dac424 - So 16.07.06 00:47
Titel: also wenn ich das Richtig verstanden habe.
Versuche mir das jetzt mal bildlich um zusetzen
dann entscheidet der Server jetzt was an die Clients gesendet wird ?

Delphi-Quelltext
1:
MyMessage := Socket.RemoteAddress+': '+Socket.ReceiveText; //original                    


ich köntte doch den String erweitern oder??


Delphi-Quelltext
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 user profile iconjasocul: Delphi-Tags hinzugefügt


Narses - So 16.07.06 00:57

user profile iconNarses hat folgendes geschrieben:
Mein lieber user profile icondac424, 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 [http://www.delphi-library.de/topic_ProtokollChatTutorial+V300_54269.html] gegeben


user profile iconNarses 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


pupu - So 16.07.06 19:34

hier ma n screenshot, damit ihr euch das vielleicht etwas besser vorstellen könnt was genau passiert...vllt hilft das ja :wink:

Moderiert von user profile iconTino: Bild als Dateianhang hochgeladen.

edit: habs so weit gelöst...aus irgendeinem Grund hatte ich aus:

Delphi-Quelltext
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:

Delphi-Quelltext
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:


Narses - Mi 13.09.06 17:17

Moin!

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

cu
Narses


Memorius - Sa 02.06.07 23:05

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-


Narses - So 03.06.07 14:35

Moin!

user profile iconMemorius 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). ;)

user profile iconMemorius 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 DYNDNS suchen, dann auf der DynDNS-Homepage registrieren (http://www.dyndns.org, 5 Hosts sind für private Anwendung kostenlos) und loslegen. :D

cu
Narses


Memorius - So 03.06.07 15:16

Danke!!!


Unknown - Di 12.06.07 15:59
Titel: Fehler aufgetreten
Hallo, bei mir is ein Fehler aufgetreten, Fehler 10061, ich hab mine Firewall auch deaktiviert aber es geht nicht....
Was soll ich tun


Narses - Di 12.06.07 16:16
Titel: Re: Fehler aufgetreten
Moin!

user profile iconUnknown hat folgendes geschrieben:
bei mir is ein Fehler aufgetreten, Fehler 10061

Der Fehler bedeutet, dass der Client sich nicht zum Server verbinden kann.

user profile iconUnknown hat folgendes geschrieben:
ich hab mine Firewall auch deaktiviert aber es geht nicht....
Was soll ich tun

Vielleicht ist das Serverprogramm nicht gestartet? Du kannst dir in einer Kommandozeile mit netstat -a anzeigen lassen, welche Ports auf dem lokalen PC "abgehört" werden (=auf eine Verbindung warten). :idea:

cu
Narses


Unknown - Mi 13.06.07 21:21

Ich weiß schon das Fehler 10061 bedeutet und das ich den Server "aufmachen" muss (sehe ich etwa so dumm aus :-P).
Naja, das mit netstat -a funzt net, aber ich glaube es liegt am Host, welche IP muss ich da angeben, vll 127.0.0.1 oder so.
Oder gibt es einen Befehl GetWindowsIP????

aber thx schonmal


Narses - Mi 13.06.07 22:37

Moin!

user profile iconUnknown hat folgendes geschrieben:
Ich weiß schon das Fehler 10061 bedeutet und das ich den Server "aufmachen" muss

Fein. ;)

user profile iconUnknown hat folgendes geschrieben:
Naja, das mit netstat -a funzt net,

Was auch immer "funzt net" konkret heißen mag... :roll:

user profile iconUnknown hat folgendes geschrieben:
aber ich glaube es liegt am Host, welche IP muss ich da angeben, vll 127.0.0.1 oder so.

Das hängt davon ab, wo der Server läuft und wie der Client ihn erreichen kann. Wenn du beide Programme auf der gleichen Maschine laufen lässt, dann wäre als Host für den Server "localhost" oder "127.0.0.1" korrekt; wenn der Server auf einer anderen Maschine läuft, als der Client, dann musst du natürlich die IP des Server-PCs eingeben (auf dem Server in einer Konsole ipconfig /alleingeben und ablesen). :idea:

cu
Narses


Kuyatzu - Di 21.08.07 15:16
Titel: Dynamischen TSockets
Hi leutz!!!!

ich habe ma ne frage oder problemm mit meinem Delphi .
ich benutzte Delphi turbo 2006 und habe naturlich "dclsockets70.bdl" nicht
und wolte das chat programm denn dynamisch erzeugen hat aber nicht geklapt er zeigt mir ne fehler meldung beim form1Creade an :

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.FormCreate(Sender: TObject);
begin
ClientSocket1 := TClientSocket.Create(Form1);
ClientSocket1.OnConnect [u]:=<span style="color: red">DynConnectEvent</span>;[/u]
ClientSocket1.Port := MY_Port;
ClientSocket1.Active := TRUE;
end;


wenn jemand ne lösung hat bitte posten.......

ps:sry meine ausdruckweise ich bin noch noobi in delphi

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


Narses - Di 21.08.07 15:23
Titel: Re: Dynamischen TSockets
Moin und :welcome: im Forum!

user profile iconKuyatzu hat folgendes geschrieben:
das chat programm denn dynamisch erzeugen hat aber nicht geklapt er zeigt mir ne fehler meldung beim form1Creade an :


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.FormCreate(Sender: TObject);
begin
ClientSocket1 := TClientSocket.Create(Form1);
ClientSocket1.OnConnect := DynConnectEvent;[/u]
ClientSocket1.Port := MY_Port;
ClientSocket1.Active := TRUE;
end;

Du hast vermutlich diese Methode nicht als Mitglied der Formularklasse deklariert (also so: procedure TForm1.Dyn...). :idea:

Schau mal in den ersten Beitrag am Ende im Anhang ist eine Version mit dynamisch erzeugten Socket-Komponenten, da ist das in der Praxis zu sehen und hier ist es auch nochmal ausführlich erklärt [http://www.delphi-library.de/topic_64438.html]. :les: ;)

cu
Narses


Kuyatzu - Di 21.08.07 15:32

erstma möchte ich mich um die sehr schnelle antwort bedanken
und werde versuchen das problem zu lösen
wenn ich noch mehr fragen habe dann weiß ich das ich auf diesem Forum bleibe das ist ihr echt geil :o

jo danke funst jetzt habe ich wohl einfach übersehen in meiner eifer mit delphi zu coden


elundril - Di 21.08.07 16:26

Gute Tutorials. Haste gut gemacht! dafür bekommste zwei Daumen hoch. :zustimm: :zustimm:

lg elundril


Kuyatzu - Sa 01.09.07 20:58

hi tut mir ja leid aber ich habe schon wieder ein fehler obwohl ich es genau so gemachr habe wie du es gesagt hast

procedure DynConnectEvent(Sender: TObject; Socket: TCustomWinSocket);
//hir ist ein Fehler "Ungenügende Forward- oder Externale-Deklaration:'TForm1.DynConnectEvent'

kannst du mir bitte helfen danke


Narses - Sa 01.09.07 23:25

Moin!

Ich schätze mal, dass du (korrekterweise) in der Deklaration das "TForm1." beim Prozedurnamen weggelassen hast, aber bei der Methode (also da, wo dann der Code der Prozedur folgt) muss ein "TForm1." hin, sonst klappt´s nicht.

cu
Narses


Kuyatzu - So 02.09.07 07:33

so mir reicht es ich weiß nicht was ich noch machen kann es funtzt immer noch nicht bitte um hilfe
hir quelltext

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
unit Unit_v0_01Beta;

interface

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

procedure FormCreate(Sender: TObject);
    procedure Form1.DynConnectEvent(Sender: TObject; Socket: TCustomWinSocket);
     //hir ist ein Fehler "Ungenügende Forward- oder Externale-Deklaration:'TForm1.DynConnectEvent'

procedure TForm1.FormCreate(Sender: TObject);
begin
  ClientSocket1 := TClientSocket.Create(Form1);
  ClientSocket1.OnConnect :=DynConnectEvent; // und hir auch
  ClientSocket1.Active := TRUE;
  ClientSocket1.Port := 73954;
end;

end.


Moderiert von user profile iconTino: Delphi-Tags hinzugefügt.


Narses - So 02.09.07 23:28

Moin!

Vorweg: Bitte verwende die Delphi-Tags für Quelltext, das kann man sonst nicht lesen (einfach den Quelltext im Editor markieren und dann auf das "+" neben "Delphi" klicken, fertig)! :mahn: ;)

user profile iconKuyatzu hat folgendes geschrieben:
ich weiß nicht was ich noch machen kann es funtzt immer noch nicht

Ich habe dir bereits geschrieben, was man da machen kann; du hast es nur nicht gemacht... :nixweiss:

Probier das mal so: :idea:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure DynConnectEvent(Sender: TObject; Socket: TCustomWinSocket);
  private
    { Private-Deklarationen }
  public
    ClientSocket1: TClientSocket;
  end;

//...

procedure TForm1.FormCreate(Sender: TObject);
begin
  ClientSocket1 := TClientSocket.Create(Form1);
  ClientSocket1.OnConnect := DynConnectEvent;
  ClientSocket1.Port := 12345// Portnummer muss im Bereich 1025..65535 sein!
  ClientSocket1.Active := TRUE; // erst Port setzen, dann öffnen!
end;

procedure TForm1.DynConnectEvent(Sender: TObject; Socket: TCustomWinSocket);
begin
  ShowMessage('Connect');
end;

cu
Narses


Kuyatzu - Di 04.09.07 21:34

aso danke habs jetzt verstanden bin noch anfänger


IamZeus - Do 04.10.07 14:01
Titel: Übers Internet?
Ist es möglich, dass ich zu Hause einen Server starte und zu ihm connecte, und jemand über das Internet auch darauf zugreift? Geht das auch, wenn ich einen Router habe?
Und zuletzt, welche IPAdresse würde man eingeben müssen, um sich zu meinem Server zu verbinden, da ich ja eine Lokale Adresse und eine öffentliche Internet-IP habe.

mfg
Zeus


Narses - Do 04.10.07 14:52
Titel: Re: Minimaler LAN/Internet-Chat mit TServer-/TClientSocket
Moin und :welcome: im Forum!

user profile iconIamZeus hat folgendes geschrieben:
Ist es möglich, dass ich zu Hause einen Server starte und zu ihm connecte, und jemand über das Internet auch darauf zugreift?

Ja, das geht.
user profile iconIamZeus hat folgendes geschrieben:
Geht das auch, wenn ich einen Router habe?

Ja, allerdings nur, wenn du ein Port-Forwarding im Router einrichtest.

user profile iconIamZeus hat folgendes geschrieben:
Und zuletzt, welche IPAdresse würde man eingeben müssen, um sich zu meinem Server zu verbinden, da ich ja eine Lokale Adresse und eine öffentliche Internet-IP habe.

user profile iconNarses im ersten Beitrag hat folgendes geschrieben:
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 http://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.

cu
Narses


IamZeus - Do 04.10.07 14:55

danke


Mann_aus_Delphi - Sa 05.04.08 12:18

Hey Leute,
ich wollte mal versuchen, ob ich auch mit dem simplen Chat eine Art Mini-Lan-Spiel zu basteln. Funktioniert auch einwandfrei, nur wenn ich versuche mehrere Strings hintereinander zuversenden, passiert es, dass sie sich zu einem zusammentun. An jeden Befehl den ich schcicke hänge ich eine Endung dran, um ihn auf der Gegenseite identifizieren u können. Beispiel:

Delphi-Quelltext
1:
2:
3:
Client.Socket.SendText('starten.xy');
Client.Socket.SendText('pause.xy');
Client.Socket.SendText('beenden.xy');


Auf der Gegenseite, bzw. auch schon beim Server kommt folgendes an:

starten.xypause.xybeenden.xy

Wie kann ich das verhindern? :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?:
Mit sleep habe ich es schon versucht und auch mit dem versenden von Leerstrings zwischendrin!
Vielen Dank schon mal im voraus!

Mann aus Delphi


Narses - Do 17.04.08 15:41

Moin!

user profile iconMann_aus_Delphi hat folgendes geschrieben:
Funktioniert auch einwandfrei, nur wenn ich versuche mehrere Strings hintereinander zuversenden, passiert es, dass sie sich zu einem zusammentun.
Funktioniert einwandfrei, nur klappt nicht richtig? :nut: :lol: (sorry, aber der musste raus)

Hier ist der Grund [http://www.delphi-library.de/topic_Datenpakete+bei+den+SocketKomponenten+auseinanderhalten_56194.html] und hier die Lösung [http://www.delphi-library.de/topic_TerminatorzeichenProtokollTutorial_54269.html]. :idea: Steht aber auch alles im ersten Beitrag. ;)

cu
Narses


GTA-Place - So 24.08.08 15:15

AntiVir erkennt neuerdings in beiden Beispiel-Archiven den Trojaner TR/ATRAPS.Gen - Kannste ja mal bei Gelegenheit als False Positiv melden.

- Verdächtigte Datei: Server.exe
- Scan mit Jotti:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
Scan taken on 24 Aug 2008 13:19:52 (GMT)  
A-Squared             Found nothing 
AntiVir               Found TR/ATRAPS.Gen  
ArcaVir               Found nothing 
Avast                 Found nothing 
AVG Antivirus         Found nothing 
BitDefender           Found nothing 
ClamAV                Found nothing 
CPsecure              Found nothing 
Dr.Web                Found nothing 
F-Prot Antivirus      Found nothing 
F-Secure Anti-Virus   Found nothing 
Fortinet              Found nothing 
Ikarus                Found nothing 
Kaspersky Anti-Virus  Found nothing 
NOD32                 Found nothing 
Norman Virus Control  Found Sandbox: W32/Malware;

[ General information ]

* File length: 163328 bytes.

[ Changes to registry ]
* Accesses Registry key "HKCU\Software\Borland\Locales".
* Accesses Registry key "HKLM\Software\Borland\Locales".
* Accesses Registry key "HKCU\Software\Borland\Delphi\Locales".

[ Security issues ]
* Scans for NetBus affected machines.

[ Process/window information ]
* Creates an event called .  

Panda Antivirus       Found nothing 
Sophos Antivirus      Found nothing 
VirusBuster           Found nothing 
VBA32                 Found nothing


- Wenn ich das Projekt selbst kompiliere mit D7PE gibt es keine Meldung mehr.


Narses - Mo 25.08.08 20:04

Moin!

user profile iconGTA-Place hat folgendes geschrieben:
AntiVir erkennt neuerdings in beiden Beispiel-Archiven den Trojaner TR/ATRAPS.Gen
Danke für den Hinweis.

Das kommt leider häufig vor, wenn man Listening-Sockets in UPX-gepackten EXEn hat... :nixweiss: Einfach die EXE löschen und selbst neu übersetzen, dann ist das "Problem" weg.

user profile iconGTA-Place hat folgendes geschrieben:
Kannste ja mal bei Gelegenheit als False Positiv melden.
Aha :? wusste bisher gar nicht, dass das geht... :shock:

cu
Narses


GTA-Place - Di 26.08.08 08:54

user profile iconNarses hat folgendes geschrieben:
user profile iconGTA-Place hat folgendes geschrieben:
Kannste ja mal bei Gelegenheit als False Positiv melden.
Aha :? wusste bisher gar nicht, dass das geht... :shock:

Einfach hier die Datei hochladen und "Verdacht auf Fehlalarm auswählen":
http://analysis.avira.com/samples/index.php

So wie ich Avira kenn ist das dann schon in den nächsten Updates behoben.


EDIT (20.09.2008): Scheinbar seit einiger Zeit behoben ;-)


knuddel - Do 18.09.08 21:01

Solche Maenner braucht das Land! Hat auf Anhieb gefunzt. Wollen eine Komminikation/Konfiguration plattformunabhaengig realisieren - Win/Linux ohne Desktop. Perfekt geschrieben - war sicher viel Arbeit. Danke..


infstar2k7 - Mo 06.10.08 21:16

Schönes Ding ;-)
Simpel, extrem hilfreich, gut verständlich, danke sehr!!


bbBowser - Mi 22.10.08 17:23

hey@all,

kaum zu glauben, aber ich befürchte es funktioniert bei mir nicht richtig. hab alles 1:1 kopiert...server und client laufen, connecten...allerdings wenn ich dann eine nachricht sende kommen schon beim server "chinesische schriftzeichen" an, die mir der auch zurücksendet. funktionieren die alten socketkomponenten denn noch einwandfrei mit windows vista? bzw wo kann das problem liegen? mit den indykomponenten hatte ich bisher kein problem dieser art, trotzde wollte ich die sockets mal ausprobieren, weil es mir doch übersichtlicher erscheint.

ich hoffe ihr habt nen plan woran es liegen könnte.

gruss bbBowser


Narses - Mi 22.10.08 18:17

Moin und :welcome: im Forum!

user profile iconbbBowser hat folgendes geschrieben Zum zitierten Posting springen:
kaum zu glauben, aber ich befürchte es funktioniert bei mir nicht richtig. hab alles 1:1 kopiert...server und client laufen, connecten...allerdings wenn ich dann eine nachricht sende kommen schon beim server "chinesische schriftzeichen" an, die mir der auch zurücksendet.
Im Archiv sind ja auch schon fertig kompilierte Programme dabei. Hast du die mal ausprobiert? Gibt es da auch diese Effekte? Wenn nicht, dann wirst du wohl oder übel einen kleinen Kopier-Fehler drin haben... :? Nebenbei: die Programme aus dem Tut laufen bei mir einwandfrei.

user profile iconbbBowser hat folgendes geschrieben Zum zitierten Posting springen:
funktionieren die alten socketkomponenten denn noch einwandfrei mit windows vista?
Da das auch nur WSA-Wrapper sind, sollte es keine Probleme geben (jedenfalls nicht bei so einem einfachen Fall).

user profile iconbbBowser hat folgendes geschrieben Zum zitierten Posting springen:
ich hoffe ihr habt nen plan woran es liegen könnte.
Da der Tut-Code wie gesagt getestet ist, vermute ich mal, dass du vielleicht irgendwo einen Tiepvehler drin hast? :nixweiss:

Ansonsten: zeig mal den Code. ;)

cu
Narses


bbBowser - Mi 22.10.08 19:03

habs jetzt mal ausprobiert: die fertig compilierten exedateien machen es ohne probleme, wenn ich allerdings die fertigen dpr dateien compiliere passiert wieder exakt das selbe.
ergo geh ich davon aus, dass es an meinem delphi liegt. ich hab das package dclsockets120.bpl anstatt das in der faq angesprochene dclsockets70.bpl(war es denke ich:P ) eingebunden, da ich letzteres nicht gefunden habe.


Narses - Do 23.10.08 01:58

Moin!

user profile iconbbBowser hat folgendes geschrieben Zum zitierten Posting springen:
habs jetzt mal ausprobiert: die fertig compilierten exedateien machen es ohne probleme,
OK, damit sollte klar sein, dass die SocketKomponenten auch unter Vista noch laufen. ;)

user profile iconbbBowser hat folgendes geschrieben Zum zitierten Posting springen:
wenn ich allerdings die fertigen dpr dateien compiliere passiert wieder exakt das selbe.
Ich frag jetzt mal ganz braun 8) du nimmst die unveränderten Code-Ordner und kompilierst das Demo-Projekt, ohne ein Zeichen im Code verändert zu haben und das klappt nicht, ja? :gruebel:

user profile iconbbBowser hat folgendes geschrieben Zum zitierten Posting springen:
ergo geh ich davon aus, dass es an meinem delphi liegt. ich hab das package dclsockets120.bpl anstatt das in der faq angesprochene dclsockets70.bpl(war es denke ich:P ) eingebunden, da ich letzteres nicht gefunden habe.
Wenn du eine Delphi-Version 12.0 hast (ich habe den Überblick verloren, welcher Produktname das nun ist :roll: D2006? TurboD? what ever...), dann sollte das genau das sein, was du brauchst. Wenn du allerdings eine andere Version verwendest, dann kann es zu komischen Effekten kommen. :nixweiss:

Was spricht gegen D7? Delphi ist eh nur für Win32 brauchbar, dann kann man auch gleich bei D7(pro) bleiben... :|

cu
Narses


Doerne - Di 28.10.08 14:45

Hallo erstmal,

bin neu hier und ich muss leider sagen ich haben das gleiche Problem wie mein Vorredner.

Habe auch die Delphi Version 12.0 (Delphi 2009).

Kann es sein das die vom Client geschickten Strings in einem anderen Format sind,
als die Strings die Delphi in das Memofeld schiebt?

Oder das Delphi intern ein anderes Zeichenformat für die beiden Komponenten benutzt?

Für Hilfe wäre ich Dankbar!

MFG
Doerne

edit:
Habe grade meinen Code in Delphi 2006 eingebunden und kompiliert und siehe da die kryptischen Zeichen sind
weg und es steht das da was ich gesendet hab.

Darum die Frage warum geht es bei Delphi 2006 und nicht bei Delphi 2009?


elundril - Di 28.10.08 16:08

kann das vielleicht wegen der Unicode-codierung sein?

lg elundril


Doerne - Di 28.10.08 16:21

Hab gerade mal versucht den String den der Server empfängt zu konvertieren.

Also wenn ich das richtig verstanden hab : UTF8ToString oder UTF8ToAnsi

Hat aber leider nichts geändert.

Habe ich die falsche Konvertierung gewählt?


DorJo - Fr 23.01.09 03:23

hmm...
ich bins mal wieder :oops:
irgendwie funktioniert das bei mir nicht!
Ich telefoniere über ein modem (kabel deutschland) ins internet an dem ein d-Link DIR 300 Router Firmware-Version 1.03 hängt.
Den Router habe ich, soweit ich es verstanden habe konfiguriert:

Moderiert von user profile iconNarses: Bild als Anhang "portweiterleitung.jpg" hochgeladen
Moderiert von user profile iconNarses: Bild als Anhang "anwendungsregeln.jpg" hochgeladen

Auch die Firewall auf dem Rechner auf dem der server läuft ist konfiguriert.
Dann habe ich den Server gestartet und mich am eigenen Rechner mit localhost verbunden. Aber wenn ich es über das Internet versuche (mit der Internet IP) funktioniert es nicht. Es kommt nur Fehler 10061

Weiß da jemand weiter?


Narses - Fr 23.01.09 14:11

Moin!

user profile iconDorJo hat folgendes geschrieben Zum zitierten Posting springen:
Den Router habe ich, soweit ich es verstanden habe konfiguriert:
[...]
Auch die Firewall auf dem Rechner auf dem der server läuft ist konfiguriert.
Sicher, dass die IP deines Rechners auch zu der Portweiterleitung im Router passt? Lässt du dir per DHCP eine Adresse von Router geben? Hast du in diesem Fall eine statische Zuordnung für eine MAC-Adresse angelegt?

user profile iconDorJo hat folgendes geschrieben Zum zitierten Posting springen:
Aber wenn ich es über das Internet versuche (mit der Internet IP) funktioniert es nicht. Es kommt nur Fehler 10061
Das probierst du aber nicht auf deinem Recher, oder (also aus dem internen Netz)? Das klappt nur, wenn es jemand "aus dem Internet" versucht. :idea:

cu
Narses


DorJo - Mo 26.01.09 04:04

Moin

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Sicher, dass die IP deines Rechners auch zu der Portweiterleitung im Router passt? Lässt du dir per DHCP eine Adresse von Router geben? Hast du in diesem Fall eine statische Zuordnung für eine MAC-Adresse angelegt?

Nun ja... ich bekomme über DHCP eine IP Adresse. Irgendwie kriege ich das nicht hin die MAC Adresse einzustellen bei der D-Link Software :( bin anscheinend zu blöd. Weiterhin nutze ich anstelle eines Lan-Kabels einen d-Lan Adapter. Deswegen muss ich DHCP benutzen.


user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Das probierst du aber nicht auf deinem Recher, oder (also aus dem internen Netz)? Das klappt nur, wenn es jemand "aus dem Internet" versucht. :idea:


Hmm... nja... ich hab es von einem anderen Rechner, welcher zwar im internen Netz hängt. Aber übers Internet (also mit der Internet-Ip)... liegts vllt. daran?

MfG

Jo


Narses - Mo 26.01.09 13:43

Moin!

user profile iconDorJo hat folgendes geschrieben Zum zitierten Posting springen:
ich bekomme über DHCP eine IP Adresse. Irgendwie kriege ich das nicht hin die MAC Adresse einzustellen bei der D-Link Software :( bin anscheinend zu blöd. Weiterhin nutze ich anstelle eines Lan-Kabels einen d-Lan Adapter. Deswegen muss ich DHCP benutzen.
DHCP ist schon OK, um die Parameter vom Router zu beziehen. Du musst allerdings ausschließen, dass du bei jeder Verbindung zum Router eine neue IP bekommst. :nixweiss: Ansonsten musst du halt jedes mal in der Router-Config prüfen, ob die dort für das Portforwarding hinterlegte Adresse noch zu deiner aktuellen passt. :?

user profile iconDorJo hat folgendes geschrieben Zum zitierten Posting springen:
ich hab es von einem anderen Rechner, welcher zwar im internen Netz hängt. Aber übers Internet (also mit der Internet-Ip)... liegts vllt. daran?
Ich kenne deinen Router nicht, aber die meisten haben Probleme, die externe IP im internen Netz korrekt aufzulösen (meiner kann´s, von den Netgear-Geräten weiß ich z.B., dass sie es nicht können). Fazit: um ganz sicher zu gehen, muss das jemand aus dem Internet probieren, vom lokalen Netz aus mit der öffentlichen IP anzufragen, könnte durchaus nicht klappen. :idea:

cu
Narses

PS: Das hier schon gelesen [http://www.delphi-library.de/topic_Portforwarding++Eine+kleine+Einfuehrung_80904.html]? ;)


jaenicke - Mo 26.01.09 19:39

user profile iconDorJo hat folgendes geschrieben Zum zitierten Posting springen:
Weiterhin nutze ich anstelle eines Lan-Kabels einen d-Lan Adapter. Deswegen muss ich DHCP benutzen.
Warum musst du das da benutzen? Ich habe bei meiner W-LAN Karte auch eine feste IP eingestellt. Diese Möglichkeit sollte es eigentlich immer geben, auch beim Steckdosen-LAN. Hast du denn einmal ausprobiert was passiert, wenn du dir eine IP aus dem Adressbereich des Routers fest zuweist? Also in den Einstellungen des Netzwerkadapters selbst?

Abgesehen davon: Woran scheitert es denn über die MAC Adresse? Bekommst du es nicht eingestellt oder funktioniert die Zuweisung nicht?


DorJo - Di 27.01.09 03:53

Zitat:
Abgesehen davon: Woran scheitert es denn über die MAC Adresse? Bekommst du es nicht eingestellt oder funktioniert die Zuweisung nicht?


Offenbar funktioniert die Zuweisung nicht! Ich stelle alles ein und drücke auf hinzufügen... und nichts passiert :(


jaenicke - Di 27.01.09 03:57

Dann bleibt wie gesagt nur eine manuelle Zuweisung einer IP. Außerdem könnte man vielleicht schauen, ob man den Router nicht doch zu einer Zuweisung per MAC bringen kann.

Dafür ist dieser Thread aber nicht der richtige Ort. Du könntest ein Thema in Off-Topic erstellen, vielleicht lässt sich da ja etwas machen.