Einzelnen Beitrag anzeigen

RedShakal
(Gast)

n/a Beiträge
 
#1

Indy TCP Client-Server Problem

  Alt 13. Jul 2009, 23:14
Hallo mal wieder, ich habe vor kurzem vorgehabt für mein Programm ein Login Script zu schreiben. Irgentwann will ich die Daten mal in einer DB speichern aber zur zeit reicht erstmal ein Test Benutzername für meine Zwecke aus. Leider stecke ich bei der Kommunukation fest. Wenn Der Client was sendet, reagiert der Server nicht. Drückt man den Knopf nochmal bekommt man einen Fehler das die Verbindung bereits bestehen würde. Ich brauch mal eine zweite Person die über den Code drüberschaut und ggf. den Fehler findet


Die Login.pas
Delphi-Quellcode:
unit login;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IniFiles, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient;

type
  TForm1 = class(TForm)
    Username: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Passwort: TEdit;
    CheckBox1: TCheckBox;
    Button1: TButton;
    Button2: TButton;
    Client: TIdTCPClient;
    procedure Button2Click(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ClientConnected(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type
  TDynStringArray = array of string;

var
  Form1 : TForm1;
  Benutzername : string;

implementation

uses registration, main;

{$R *.dfm}

function Explode(const Separator, S :String; Limit :Integer = 0): TDynStringArray;
  var
    SepLen: Integer;
    F, P: PChar;
begin
  SetLength(Result, 0);
  if (S = '') or (Limit < 0) then
    Exit;
  if Separator = 'then
    begin
      SetLength(Result, 1);
      Result[0] := S;
      Exit;
    end;
  SepLen := Length(Separator);

  P := PChar(S);
  while P^ <> #0 do
    begin
      F := P;
      P := AnsiStrPos(P, PChar(Separator));
      if (P = nil) or ((Limit > 0) and (Length(Result) = Limit - 1)) then
        P := StrEnd(F);
      SetLength(Result, Length(Result) + 1);
      SetString(Result[High(Result)], F, P - F);
      F := P;
      if P = Separator then
        SetLength(Result, Length(Result) + 1);
      while (P^ <> #0) and (P - F < SepLen) do
        Inc(P);
    end;
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
Form2.Visible := true;
Form1.Visible := false;
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
var ini: TIniFile;
begin
  ini:=TIniFile.create(ExtractFilePath(ParamStr(0))+ 'settings.ini');

  if Checkbox1.Checked = true then
    begin
      ini.WriteBool('Login','Save',true);
      ini.WriteString('Login','Username',Username.Text);
      ini.WriteString('Login','Passwort',Passwort.Text);
    end
  else
    begin
      ini.WriteBool('Login','Save',false);
      ini.WriteString('Login','Username','');
      ini.WriteString('Login','Passwort','');
    end;
  ini.free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Benutzername := Username.Text;
  Client.Connect(5000);
  Client.Write('Login' + '|' + Form1.Username.Text + '|' + Form1.Passwort.Text);
end;

procedure TForm1.FormCreate(Sender: TObject);
var ini: TIniFile;
begin
  ini:=TIniFile.create(ExtractFilePath(ParamStr(0))+ 'settings.ini');
  try
    Client.Host := ini.ReadString('Login','ServerIP','');
    Client.Port := ini.ReadInteger('Login','ServerPort',0);
    Username.Text := ini.ReadString('Login','Username','');
    Passwort.Text := ini.ReadString('Login','Passwort','');
    Checkbox1.Checked := ini.ReadBool('Login','Save',false);
  finally
    ini.free;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Form3.Chat.Disconnect();
  Form1.Client.Disconnect;
end;

procedure TForm1.ClientConnected(Sender: TObject);
var
  Buffer : String;
  StrArr : TDynStringArray;
begin

 Buffer := Client.ReadLn;

  if Length(Buffer) > 0 then
    begin
      StrArr := Explode('|', Buffer);
    end;

  if StrArr[0] = 'Connectedthen
    begin
      Form1.Visible := false;
      Form3.Visible := true;
      try
        Form3.Chat.Connect(3000);
        Form3.Chat.Nick := 'KKND|'+Benutzername;
        Form3.Chat.AltNick := 'KKND|'+Benutzername;
        Form3.Timer1.Enabled := true;
      except
        showmessage('Fehler beim Verbinden!');
      end;

  if StrArr[0] = 'Passwortthen
    begin
      showmessage('Benutzername und/oder Passwort falsch!');
      Client.Disconnect;
    end;
   end;
end;

end.

Der Server:

Delphi-Quellcode:
unit server;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdTCPServer, StdCtrls;

type
  TForm1 = class(TForm)
    Server: TIdTCPServer;
    procedure ServerConnect(AThread: TIdPeerThread);
    procedure ServerExecute(AThread: TIdPeerThread);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type
  TDynStringArray = array of string;


var
  Form1: TForm1;

implementation

{$R *.dfm}

function Explode(const Separator, S :String; Limit :Integer = 0): TDynStringArray;
  var
    SepLen: Integer;
    F, P: PChar;
begin
  SetLength(Result, 0);
  if (S = '') or (Limit < 0) then
    Exit;
  if Separator = 'then
    begin
      SetLength(Result, 1);
      Result[0] := S;
      Exit;
    end;
  SepLen := Length(Separator);

  P := PChar(S);
  while P^ <> #0 do
    begin
      F := P;
      P := AnsiStrPos(P, PChar(Separator));
      if (P = nil) or ((Limit > 0) and (Length(Result) = Limit - 1)) then
        P := StrEnd(F);
      SetLength(Result, Length(Result) + 1);
      SetString(Result[High(Result)], F, P - F);
      F := P;
      if P = Separator then
        SetLength(Result, Length(Result) + 1);
      while (P^ <> #0) and (P - F < SepLen) do
        Inc(P);
    end;
end;


procedure TForm1.ServerConnect(AThread: TIdPeerThread);
begin
  AThread.Connection.MaxLineLength := 1024*1024;
end;

procedure TForm1.ServerExecute(AThread: TIdPeerThread);
var
  Login: string;
  StrArr : TDynStringArray;
begin
  Login := AThread.Connection.ReadLn();

  if Length(Login) > 0 then
    begin
      StrArr := Explode('|', Login);
    end;

  if StrArr[0] = 'Loginthen
    begin
      if (StrArr[1] = 'Testuser') and (StrArr[2] = 'Testpass') then
        begin
          AThread.Connection.WriteLn('Connected');
        end
      else
        begin
          AThread.Connection.WriteLn('Passwort');
        end;
    end;

end;

end.
Er soll nur schauen ob die beiden eingaben übereinstimmen und ggf. das 3te Form entsprechend öffnen.

Da habe ich gleich noch eine weitere Frage: Gibts eine bessere möglichkeit aus mit Form.Visible zu arbeiten? Das scheint mir leider sehr uneffektiv zu sein. Leider komme ich mit Form2.Create(self) auch nicht wirklich weiter. Wenn jemand eine Idee hat ich bin für alles offen

http://img512.imageshack.us/img512/3553/13132123123.jpg
  Mit Zitat antworten Zitat