Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi TClientSocket: OnRead wird zu oft aufgerufen (https://www.delphipraxis.net/20874-tclientsocket-onread-wird-zu-oft-aufgerufen.html)

Andreas Hartmann 24. Apr 2004 17:01


TClientSocket: OnRead wird zu oft aufgerufen
 
Hallo,

ich habe einen Chat realisiert: Serverseitig nehme ich den Indy TCP Server, das geht alles.

Clientseitig benutze ich den ClientSocket, weil der Indy TCP Client trotz AntiFreeze oft hängt.
Nun habe ich in dem OnRead-Ereignis dieses stehen:

ChatWindow.Lines.Append(Socket.ReceiveText);

Das Chatfenster zeigt nach dem Connect dieses an:
This is the SecureChat Server on computer2
Guest 25 betritt den Chat.
Guest 25 betritt den Chat.
Guest 25 betritt den Chat.
Guest 25 betritt den Chat.
Guest 25 betritt den Chat.
Guest 25 betritt den Chat.
Guest 25 betritt den Chat.
Guest 25 betritt den Chat.
Your Nickname is Guest 25


Eigentlich müsste dort stehen:
This is the SecureChat Server on computer2
Guest 25 betritt den Chat.
Your Nickname is Guest 25

Wenn ich mit Putty (Universal-Client) connecte, steht dort das richtige.
Was kann ich tun?

MfG, Andreas

Ultimator 29. Apr 2004 15:42

Re: TClientSocket: OnRead wird zu oft aufgerufen
 
Vielleicht wäre etwas Code ganz nett? So wird man dir wahrscheinlich schlecht helfen können.

Andreas Hartmann 29. Apr 2004 15:57

Re: TClientSocket: OnRead wird zu oft aufgerufen
 
Hier ist der Code des Servers, die Prozedur, die das Empfangen und Senden regelt:

Delphi-Quellcode:
procedure TSecureChatServerService.TCPServerConnect(
  AThread: TIdPeerThread);
var
  Msg: String;
  Client: TClient;
  N: Integer;
  TempStr: String;
begin
  Inc(GuestNum);
  AThread.Connection.WriteLn('This is the SecureChat Server on ' + AThread.Connection.LocalName);
  BroadcastMsg('Guest ' + inttostr(GuestNum) + ' betritt den Chat.');
  Client := TClient.Create(Self);
  Client.Name := 'Guest ' + inttostr(GuestNum);
  Client.Thread := AThread;
  PublicRoom.AddClient(Client);
  Client.Room := PublicRoom;
  ClientList.AddClient(Client);
  Client.SendMessage('Your Nickname is ' + Client.Name, true);
  while AThread.Connection.Connected do
  begin
    Msg := AThread.Connection.ReadLn;
    if (Msg = '#~CMD: DISCONNECT') then
    begin
      Client.SendMessage('Verbindung wird getrennt. Auf Wiedersehen!', true);
      Client.Room.RemoveClient(Client);
      ClientList.RemoveClient(Client);
      AThread.Connection.Disconnect;
    end else
    begin
      Client := ClientList.FindClient(Client.Thread);
      if Pos('#~CMD:', Msg) = 1 then
      begin
        TempStr := ProcessCommand(Msg, Client);
        if TempStr <> '' then Client.SendMessage(TempStr, true);
      end else
      try
        for N := 0 to Client.Room.ClientsCount-1 do
        begin
          if Assigned(Client.Room.Client(N).Thread) then
            Client.Room.Client(N).SendMessage(Client.Name + ': ' + Msg, true);
        end;
      except on Exception do
        Client.SendMessage('Exception...', true);
      end;
    end;
  end;
  BroadcastMsg(Client.Name + ' verlässt den Chat.');
  Client.Destroy;
end;

procedure TSecureChatServerService.BroadcastMsg(Msg: String);
var N: Integer;
begin
  try
  for N := 0 to ClientList.ClientCount-1 do ClientList.Client(N).SendMessage(Msg, true);
  except on Exception do ; end;
end;
Hier ist die Klasse TClient:
Delphi-Quellcode:
  TClient = class(TComponent)
  private
    fName: String;
    fRoom: TChatRoom;
    fKeyE: String;
    fKeyN: String;
    fThread: TIdPeerThread;
  public
    function SendMessage(Msg: String; Encrypted: Boolean): Boolean;
  published
    property Name: String read fName write FName;
    property Room: TChatRoom read fRoom write fRoom;
    property KeyE: String read fKeyE write fKeyE;
    property KeyN: String read fKeyN write fKeyN;
    property Thread: TIdPeerThread read fThread write fThread;
  end;

//und weitere Typen...

function TClient.SendMessage(Msg: String; Encrypted: Boolean): Boolean;
var
  EncMsg: String;
begin
  if Assigned(Self.Thread) then
  begin
    try
      if Encrypted then
      begin
        EncMsg := Msg;
        //Hier Code für die Verschlüsselung einfügen...
        Thread.Connection.WriteLn(EncMsg);
      end else
      begin
        Thread.Connection.WriteLn(Msg);
      end;
      Result := true;
    except on Exception do
      Result := false;
    end;
  end else Result := false;
end;
TChatRoom ist abgeleitet von TComponent und hat eine TList mit Client-Objekten.

Client-Code kommt gleich...

MfG, Andreas

Andreas Hartmann 29. Apr 2004 16:12

Re: TClientSocket: OnRead wird zu oft aufgerufen
 
Hier die Prozedur, die beim Client mit OnRead des ClientSockets verbunden ist:

Delphi-Quellcode:
procedure TChatConnectionForm.ClientSocketRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  DecStr: String;
begin
  DecStr := Socket.ReceiveText;
  //Hier Code für die Entschlüsselung einfügen
  ChatWindow.Lines.Append(DecStr);
  ChatWindow.Perform(EM_SCROLLCARET, 0, 0);
end;
MfG, Andreas


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz