Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi on client read (https://www.delphipraxis.net/93418-client-read.html)

Karg 5. Jun 2007 17:41


on client read
 
hi @ all,
ich bin neu hier und muss sagen, dass board gefällt mir überaus gut.

Jetzt aber zu meinem problem:
ich hab einen server und einen client erstellt und der client sendet dem server einen text zu.

Der server liest den text dann mit onclientread aus und zeigt ihn per showmessage.

Das funktioniert auch prima, nur kommt nicht nur der gesendete text, sondern es öffnen sich noch mehrere fenster, in denen einzelne buchstaben oder ziffern stehen.

Wie kommen die zustande und wie krieg ich das weg.

hier mal der code:

server:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
//application.showmainform:=false;
clientsocket1.port:=2000;
clientsocket1.host:='mille.no-ip.info';
clientsocket1.active:=true;
timer1.enabled:=true;

end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if (clientsocket1.Socket.Connected=false)
   then clientsocket1.active:=true
   else timer1.enabled:=false;
end;

procedure TForm1.ClientSocket1Error(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
errorcode:=0;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
clientsocket1.Socket.SendText('test');
end;

client:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
serversocket1.port:=2000;
serversocket1.active:=true;
end;



procedure TForm1.ServerSocket1ClientError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
errorcode:=0;
showmessage('fehler');
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
showmessage(socket.receivetext);
end;
[edit=SirThornberry]Programmiersprache und Titel korrigiert - Mfg, SirThornberry[/edit]

Zacherl 5. Jun 2007 18:28

Re: on client read [Porblem]
 
Dies passiert, da die Delphi VCL nicht threadsafe ist. Beschäftige dich mal mit dem Delphi-Referenz durchsuchenSynchronize Aufruf ..

thkerkmann 5. Jun 2007 19:15

Re: on client read
 
Hi und guten Abend,

@Florian Bernd: Ich sehe hier keinen Thread und auch keinen Grund für Synchronize.

Gruss

Muetze1 5. Jun 2007 19:20

Re: on client read [Porblem]
 
Zitat:

Zitat von Florian Bernd
Dies passiert, da die Delphi VCL nicht threadsafe ist. Beschäftige dich mal mit dem Delphi-Referenz durchsuchenSynchronize Aufruf ..

Hä? Was hat dies damit zu tun?

@Karg

Die Sockets übertragen einfach nur die Daten. Dabei garantieren sie dir keine Übertragung als Ganzes, sondern sie teilen die Daten wie sie sie gerade übertragen bekommen auf. So kann es abhängig von vielen Faktoren dazu kommen, dass du immer nur Teile bekommst. Von daher musst du über mehrere ClientRead Aufrufe die Daten sammeln, bis du ein Datenpacket an sich zusammen hast. Deshalb ist ein Protokoll nötig, damit du weisst, wann deine empfangenen Daten komplett sind und wann noch was fehlt und du noch weitere OnClientRead Aufrufe abwarten musst.

Als einfaches Protokoll würde schon reichen, dass du am Ende einer Botschaft ein besonderes Zeichen anhängst, welches dir auf der Empfangseite das Ende einer Botschaft anzeigt und somit ob du eine komplette Botschaft empfangen hast und wo diese aufhört (bzw. sogar die nächste anfängt).

Zacherl 5. Jun 2007 20:28

Re: on client read
 
Arhg, war bei den Indys .. die haben ja threaded-Events. Sorry ..

Karg 6. Jun 2007 10:42

Re: on client read
 
vielen dank schon mal für die hilfe...

aber das mit dem protokoll ist mir noch unverständlich, wie ich das realisieren soll.
könnte mir jemand vielleicht einen ungefähren code schreiben, um mir auf die sprünge zu helfen.

danke

Der_Unwissende 6. Jun 2007 11:29

Re: on client read
 
Hi und erstmal Herzlich Willkommen in der DP :dp:

Das was Muetze meint ist, dass Du einfach die Daten, die Du mit OnClientRead empfängst pufferst. Damit umgehst Du Dein jetziges Problem. Dazu legst Du einfach eine String-Variable an, die global verfügbar ist. Wenn Du eine Klasse verwendest, so bietet sich eine private Instanzvariable (Variable einfach im Private-Abschnitt anlegen) an.
Beim Senden einer Botschaft hängst Du immer ein Zeichen ran, dass ihr Ende markiert. Sinnvoll ist es, dass Du also ein Zeichen nimmst, dass nicht in der Botschaft selbst erwartet wird. Häufig wird hier das Zeilenende Zeichen Carriage Return (CR) verwendet. Dein Senden hat also die Form:

Delphi-Quellcode:
procedure sendMessage(const txt: String);
var message: String;
begin
  message := txt + chr(13); // chr(13) = CR
 
  // jetzt die message senden
  ...
end;
Auf der anderen Seite weißt Du nun, das egal was gesendet wird immer mit dem Zeichen chr(13) endet. Empfängst Du jetzt einen String, ist der nur ein Teil der gesamten Botschaft, bis Du eben chr(13) findest. Was auch immer Du jetzt empfängst hängst Du einfach an den Puffer an. Der ist am Anfang leer, kommt etwas an, wird das einfach angehangen.
Nach jedem Anhängen kannst Du dann schauen, ob Du hier eine vollständige Botschaft findest. Das ist immer dann der Fall, wenn das Zeichen chr(13) im Puffer findest.

Delphi-Quellcode:
// Prüfen ob das Zeichen im String ist
if pos(chr(13), buffer) > 0 then
Was Du nun noch machen musst ist den Teilstring von Position 1 bis zum ersten Auftreten von chr(13) zu kopieren (das ist dann die empfangene Nachricht). Dazu gibt es den Copy-Befehl (einfach mal suchen, findest Du eine Menge zu). Zuguter Letzt einfach den Pufferinhalt durch den hinteren Teil des Strings (der nach dem ersten Chr(13) kommt) ersetzen. Das ist nötig, da Du natürlich auch einen zweiten String direkt im Anschluss empfangen kannst und davon kann dann auch ein Teil hinter dem Trennzeichen der ersten Nachricht landen.

Gruß Der Unwissende

Karg 6. Jun 2007 12:39

Re: on client read
 
ok danke, dass war sehr hilfreich.
Jetzt hab ich aber noch ein problem und zwar habt ihr im code gesehen,
dass ich beim host folgendes geschrieben habe:

server.host:='mille.no-ip.info';

Ihr wisst sicherlich alle, dass es sich hier um eine dyn-dns handelt.
Das Problem ist jetzt, dass das Programm nicht funktioniert, wenn ich die dyn.dns, wie oben geschrieben, verwende.
Setze ich anstatt der dyn-dns 127.0.0.1 ein, geht alles reibungsfrei.

Kann mir jemand sagen, was ich da machen muss??

SirThornberry 6. Jun 2007 14:04

Re: on client read
 
wenn du hinter einem router sitzt musst du diesen so einstellen das die Anfragen auf deinen PC weitergeleitet werden. Wenn du eine Firewall hast musst du diese so einstellen das der verwendete Port offen bleibt für Anfragen.

Karg 6. Jun 2007 14:16

Re: on client read
 
das hab ich alles gemacht.
Daran kann es auf keinen fall liegen


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:45 Uhr.
Seite 1 von 2  1 2      

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