Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - TCPServer sendet an TCPClient


Jakane - Mo 17.08.15 21:07
Titel: TCPServer sendet an TCPClient
Hallo Delphi-Helfer :)

ich bin schon ganz am verzweifeln :(
Ich habe 2 Exen.
Eine soll den Server darstellen, der andere den Client.

Das Senden von Nachrichten vom Client zum Server geht problemlos.
Aber ich krieg es nicht hin das der Server "Gelesen" zum Client zurück schickt.

Habe schon viele Foren durchschaut, aber die helfen mir leider nicht.

Kann mir jemand sagen wo ich angreifen muss und womit?


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:
unit ServerHaupt;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Web.Win.Sockets, Vcl.StdCtrls;

type
  TFServerHaupt = class(TForm)
    Server: TTcpServer;
    Button1: TButton;
    Memo1: TMemo;
    Edit1: TEdit;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure ServerAccept(Sender: TObject; ClientSocket: TCustomIpClient);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  FServerHaupt: TFServerHaupt;

implementation

{$R *.dfm}

uses dataKreta;

procedure TFServerHaupt.Button1Click(Sender: TObject);
begin
  if Server.Active then
  begin
    Server.Active := False;
    Button1.Caption := 'Server aus';
  end
  else
  begin
    Server.Active := True;
    Button1.Caption := 'Server an';
  end;
end;

procedure TFServerHaupt.Button2Click(Sender: TObject);
begin
  Server.Sendln('Gelesen');
end;

procedure TFServerHaupt.ServerAccept(Sender: TObject;
  ClientSocket: TCustomIpClient);
begin
  Memo1.Lines.Add('Client (' + FormatDateTime('hh:mm', Now) + '): ' + ClientSocket.Receiveln);
  ClientSocket.Sendln('Gelesen');
end;

procedure TFServerHaupt.FormCreate(Sender: TObject);
begin
  DMKreta := TDMKreta.Create(Self);
  Server.LocalHost := DMKreta.ServerHost;
  Server.RemoteHost := DMKreta.ServerHost;
  Server.LocalPort := DMKreta.ServerPort;
  Server.RemotePort := DMKreta.ServerPort;
end;

end.


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:
unit ClientHaupt;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Web.Win.Sockets, Vcl.StdCtrls;

type
  TFClientHaupt = class(TForm)
    Client: TTcpClient;
    Edit1: TEdit;
    Button2: TButton;
    Memo1: TMemo;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure ClientReceive(Sender: TObject; Buf: PAnsiChar;
      var DataLen: Integer);
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  FClientHaupt: TFClientHaupt;

implementation

{$R *.dfm}

uses dataKreta;

procedure TFClientHaupt.Button1Click(Sender: TObject);
begin
  Client.Receiveln;
end;

procedure TFClientHaupt.Button2Click(Sender: TObject);
begin
  Client.Active := True;
  Client.Sendln(Edit1.Text);
  Client.Active := False;
end;

procedure TFClientHaupt.ClientReceive(Sender: TObject; Buf: PAnsiChar;
  var DataLen: Integer);
begin
  Memo1.Lines.Add('Server (' + FormatDateTime('hh:mm', Now) + '): ' + Buf + ' (' + inttostr(datalen) + ')');
end;

procedure TFClientHaupt.FormCreate(Sender: TObject);
begin
  DMKreta := TDMKreta.Create(Self);
  Client.RemoteHost := DMKreta.ServerHost;
  Client.RemotePort := DMKreta.ServerPort;
end;

end.


mandras - Di 18.08.15 00:18

vielleicht hilft Dir dies:

http://www.delphipraxis.net/82849-tcpserver-tcpclient-senden-und-empfangen.html


Jakane - Di 18.08.15 12:20

Leider nicht :(

Dieser Thread ist einer wo ich ewig gegrübbelt und versucht habe

Moderiert von user profile iconNarses: Beiträge zusammengefasst

Wenn der Server active ist, und mein Client sendet etwas, bekomm ich "3" zurück.
Ist der Server inactive, und mein Client sendet etwas, bekomme ich "-1" zurück.
Wenn der Server etwas senden will, bekomme ich immer "-1" zurück.

Ist das vlt. ein Hinweis auf irgendwas?

Wenn ich alle Client-Ereignisse mit einem Memo1.Lines.Add(...) versehe, reagiert der Client nicht wenn der Server was sendet :(


Muck - Di 18.08.15 19:13

Hallo

check doch mal Button2Click in Deinem Client Programm.

Du sendest was zum Server gefolgt von einem Disconnect vom Server. Das setzen von Active auf False ist wie ein disconnect.
Also, lass den Client mal Active und Du solltest zumindest eine Antwort sehen.

Wie auch immer verweise ich auf Tutorials hier, insbesondere auf das Einsetzen von Protokolls bei der Datenuebertragung via TCP/IP besonders wenn Internet im spiel ist.
Beispiel: Ein gesendetes 'GELESEN' kann als GEL und ESEN empfangen werden.

Viel Spass

Markus


Jakane - Di 18.08.15 20:10


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TFClientHaupt.Button2Click(Sender: TObject);
begin
  Client.Active := True;
  Client.Sendln(Edit1.Text);
  Client.Active := False;
end;

Mein Problem ist nicht das Senden vom Client zum Server, das funktioniert tadellos und so wie es soll


Delphi-Quelltext
1:
2:
3:
4:
procedure TFServerHaupt.Button2Click(Sender: TObject);
begin
  Server.Sendln('Gelesen');
end;
bzw.

Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TFServerHaupt.ServerAccept(Sender: TObject;
  ClientSocket: TCustomIpClient);
begin
  ClientSocket.Sendln('Gelesen');
end;

ist das was nicht funktioniert

Ich will das der Server etwas zum Client sendet


mandras - Di 18.08.15 20:23

Der tcpClient empfängt im Gegensatz zum tcpServer nur, wenn ihm das explizit gesagt wurde.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.Button2Click(Sender: TObject);
begin
 tcpclnt1.Active := True;
 tcpclnt1.Sendln(Edt1.Text);
 tcpclnt1.Receiveln;                         // <-----!!!!
 tcpclnt1.Active := false;
end;


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


Jakane - Mi 19.08.15 20:27

Und ich hab die ganze Zeit versucht mit einem "Lesen" schalter die Nachricht zu kriegen, aber so reicht mir das auch völlig aus :D danke


mandras - Mi 19.08.15 21:59

Da müßtest Du wirklich schnell klicken können.
Solange der ClientSocket nicht auf empfangen gestellt ist (wie mittels zB ReceiveLn) werden alle eingehenden Daten auf diesen verworfen. Es erfolgt keine Zwischenspeicherung durch die Komponente oder das Betrübssystem.