Entwickler-Ecke

Internet / Netzwerk - Bei Indy vom TCP-Server zum Client senden


Slowmo - Di 26.07.05 16:42
Titel: Bei Indy vom TCP-Server zum Client senden
Ich hab ein Problem, ich sende bisher immer Daten vom Client zum Server und lese diese mit dem onExecute Ereignis aus. Doch ich möchte auch anderst herum Strings und Integer senden, doch wie kann man das realisieren, es gibt ja beim Client kein onExecute Ereignis und beim Server kann man ja auch nich mit TCPServer.WriteLn ?


StefanH - Di 26.07.05 18:26
Titel: Re: Bei Indy vom TCP-Server zum Client senden
user profile iconSlowmo hat folgendes geschrieben:
Ich hab ein Problem, ich sende bisher immer Daten vom Client zum Server und lese diese mit dem onExecute Ereignis aus. Doch ich möchte auch anderst herum Strings und Integer senden, doch wie kann man das realisieren, es gibt ja beim Client kein onExecute Ereignis und beim Server kann man ja auch nich mit TCPServer.WriteLn ?


schau dir z.B. die Chatdemo von Indy an.. da stehts u.a ;)


Slowmo - Di 26.07.05 19:25

Die hab ich mir schon angekuckt aber irgendwie versteh ich da nur Bahnhof...


maxk - Di 26.07.05 20:11

Hi,
auf deine erste Frage ganz kurz: TidTCPClient fragt nicht automatisch ab, ob neue Nachrichten vorhanden sind. Du musst dies selber tun, indem du mit idTCPClient1.Socket.Readable(0) prüfst und bei Erfolg Daten ausliest, das packst du am Besten in einen extra Suche in: Delphi-Forum, Delphi-Library "THREAD" oder einen TTimer.
Zur zweiten Frage: Der TidTCPServer ist in der Lage mehrere Clientverbindungen zu verwalten, d.h. es können sich mehrere Rechner mit deinem Server verbinden. Dadurch gibt es auch nicht die Verbindung, wie beim Client. Du kannst aber mittels Broadcasting an alle verbundenen Clients etwas senden.

Ansonsten schau dir mal Suche in: Delphi-Forum, Delphi-Library "SIMPLETCP" von user profile iconUdontknow an.

Gruß,
maxk


Slowmo - Mi 27.07.05 13:15

Geht das mit dem Senden auch einfacher als bei der Indy-Demo, weil mit meinem Server soll sich sowieso nur ein Client verbinden können, muss man das dann trotzdem mit einer TThreadList machen ??

Und ich hab das mit dem Timer zum auslösen einmal probiert, aber wenn ich zum Server connecten will stürzt der Client jetzt ab, hab ich was falsch gemacht?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
if TcpClient.Connected then
if TcpClient.Socket.Readable(0then
begin
try
ReadID:=TcpClient.ReadInteger;
Read_Timer.Enabled:=False;
if ReadID=1 then
        begin
        M_Chat.Lines.Add('Der Server hat das Programm verlassen');
        TcpClient.Disconnect;
        end;
ReadID:=0;
finally
Read_Timer.Enabled:=True;
end;
end;


Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt.


maxk - Mi 27.07.05 15:48

gar nichts. Was verstehst du den unter Abstürzen, dass das gesamte System einfriert und nurnoch der Hardwarereset hilft? Das kann ich mir eigentlich nicht vorstellen ;)

Gruß,
maxk


Slowmo - Mi 27.07.05 17:37

Natürlich nicht :shock:, aber des Programm reagiert halt nicht mahr und lässt sich nur noch über den Taskmanager bzw. Delphi beenden.


maxk - Mi 27.07.05 21:16

Klingt nach ner Endlosschleife :roll: Setz mal einen Haltepunkt bei if TcpClient.Connected then und steppe ab dort mit F8 weiter. Wenn er in der Zeile mit ReadInteger bleiben hängt, sendet der Server nicht genügend Daten.


Gruß,
maxk


Slowmo - Do 28.07.05 12:36

OK, ich hab jetzt rausgefunden dass es nicht daran liegt sondern am onConnect-Ereignis des Servers, doch ich kann da keinen Fehler entdecken.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure THost.TCPServerConnect(AThread: TIdPeerThread);
var
  NewClient: PClient;

begin
  GetMem(NewClient, SizeOf(TClient));

  NewClient.DNS         := AThread.Connection.LocalName;
  NewClient.Connected   := Now;
  NewClient.LastAction  := NewClient.Connected;
  NewClient.Thread      :=AThread;

  AThread.Data:=TObject(NewClient);

  try
    Clients.LockList.Add(NewClient);
  finally
    Clients.UnlockList;
  end;
end;


Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt.


maxk - Do 28.07.05 12:58

Zeile 15 bis 19 solltest du weglassen. Ich weiss gar nicht, was du da eigentlich vor hattest. Auf das Object kannst du immer über AThread.Data zugreifen - den Rest übernehmen die Indy selber. Ich sehe ehrlich gesagt auch nicht durch deine Pointer durch, aber ich geh mal davon aus, dass du dir dabei was gedacht hast - ich hätte es ganz simpel mit eine Ableitung von TObject gemacht :roll: Ansonsten: Durchsteppen. Das ist ein super Feature, womit sich die meisten Fehler finden lassen.

Gruß,
maxk


PS: Bitte verwende demnächst die [delphi]-Tags

// Edit: Ich bin mal davon ausgegangen, dass Clients etwas mit TidTCPServer.Threads zu tun hat (wegen Lock- und Unlocklist).