AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke ICS TWSocket Eingehende Verbindung
Thema durchsuchen
Ansicht
Themen-Optionen

ICS TWSocket Eingehende Verbindung

Ein Thema von Captnemo · begonnen am 16. Jun 2014 · letzter Beitrag vom 17. Jun 2014
Antwort Antwort
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#1

ICS TWSocket Eingehende Verbindung

  Alt 16. Jun 2014, 12:58
Hi,

ich versuche mich gerade mit den ICS-Komponenten. Explizit eine Eingehende Verbindung per TCP über TWSocket.
Laut Wiki soll ich im Event "SessionAvailable" folgendes machen:
Zitat:
The following example implements the OnSessionAvailable of a simple TCP-Server which transfers the accepted connection to another socket so that other incomming connections can be accepted as well. Since the socket the connection is transfered to is a global variable here only one connection can be accepted, but this example is simply for showing the basics.
var socket:TMySocket; // a descendant of TWSocket with overwritten OnDataAvailable

Delphi-Quellcode:
 procedure TMyServer.MyOnSessionAvailable(Sender: TObject; ErrCode: Word);
 var NewS:TSocket;
 begin
   if ErrCode <> 0 then exit;
 
   NewS:=Accept;
   socket:=TMySocket.create(nil);
   socket.dup(NewS);
 end;
Ich finde nur in XE4 nirgends die Klasse TSocket. Kann mir jemand auf die Sprünge helfen?
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: ICS TWSocket Eingehende Verbindung

  Alt 16. Jun 2014, 13:01
Ist in der Unit WinSock
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#3

AW: ICS TWSocket Eingehende Verbindung

  Alt 16. Jun 2014, 14:01
Dann meckert er bei mir
[dcc32 FEhler] clt_main.pas(118): E2035 Nicht genügend wirkliche Parameter

bei dem
mysocket:=accept;

Aber das es im Wiki von ICS so beschrieben steht, dachte ich, dass ich das so verwenden kann.
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: ICS TWSocket Eingehende Verbindung

  Alt 16. Jun 2014, 14:03
Wo/wie ist denn Accept deklariert?
Markus Kinzler
  Mit Zitat antworten Zitat
ensaron

Registriert seit: 29. Aug 2008
Ort: 10369 Berlin
63 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: ICS TWSocket Eingehende Verbindung

  Alt 16. Jun 2014, 14:26
Ich vermute mal, an dieser Stelle ist TSocket aus der Unit OverbyteIcsWSocket gemeint.
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#6

AW: ICS TWSocket Eingehende Verbindung

  Alt 16. Jun 2014, 16:46
ich habe es mal geändert in
mysocket:=(sender as TWSocket).Accept; und dann klappt es (frag mich aber, wie die das dann mit dem Beispielcode im Wiki geschafft haben).

Leider komme ich aber immer noch nicht zu dem gewünschten Ergebnis.

Ich habe auf der Form 2 TWSocket's. Einer wird mit Listen als Server gestartet, und über den anderen kann man auf einen Port eine Nachricht schicken lassen. Entweder an sich selbst oder halt an eine zweite Instanz (dann natürlich mit einsprechenden Ports).

Ziel dieses Projekt's ist es für mich erst einmal, mir zu verdeutlichen, wie das mit ICS funktioniert. (Also kein Kundenprojekt).

Hier mal mein Übungsprojekt:
Delphi-Quellcode:
unit clt_main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, JvExControls, JvComCtrls,
  Vcl.ExtCtrls, OverbyteIcsLogger,
  OverbyteIcsWndControl, OverbyteIcsWSocket, JvExStdCtrls, JvEdit,
  JvValidateEdit, Vcl.ComCtrls, winsock;

type
  Tfrm_main = class(TForm)
    lbl1: TLabel;
    edt_ip1: TJvIPAddress;
    edt_text: TEdit;
    btn_send: TButton;
    lbl2: TLabel;
    ipserver: TWSocket;
    icslgr1: TIcsLogger;
    mmo_nachrichten: TMemo;
    edt_port: TJvValidateEdit;
    btn_start: TButton;
    stat1: TStatusBar;
    ipclient: TWSocket;
    edt_sendport: TJvValidateEdit;
    lbl3: TLabel;
    lbl4: TLabel;
    lbl5: TLabel;
    procedure FormShow(Sender: TObject);
    procedure btn_sendClick(Sender: TObject);
    procedure btn_startClick(Sender: TObject);
    procedure ipserverChangeState(Sender: TObject; OldState,
      NewState: TSocketState);
    procedure ipserverDataAvailable(Sender: TObject; ErrCode: Word);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ipserverSessionAvailable(Sender: TObject; ErrCode: Word);
    procedure ipclientSessionConnected(Sender: TObject; ErrCode: Word);
    procedure ipserverSessionClosed(Sender: TObject; ErrCode: Word);
    procedure ipclientSessionClosed(Sender: TObject; ErrCode: Word);
    procedure ipserverSessionConnected(Sender: TObject; ErrCode: Word);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    ServerSocket: TWSocket;
    SendStringBuffer: TStringList;
    function GetTWSocketState(Socket: TWSocket): string;
    { Public-Deklarationen }
  end;

var
  frm_main: Tfrm_main;

implementation

{$R *.dfm}

function Tfrm_main.GetTWSocketState(Socket: TWSocket): string;
begin
  Result:='';
  case Socket.state of
    wsInvalidState: Result:='wsInvalidState';
    wsOpened: Result:='wsOpened';
    wsBound: Result:='wsBound';
    wsConnecting: Result:='wsConnecting';
    wsSocksConnected: Result:='wsSocksConnected';
    wsConnected: Result:='wsConnected';
    wsAccepting: Result:='wsAccepting';
    wsListening: Result:='wsListening';
    wsClosed: Result:='wsClosed';
  end;
end;

procedure Tfrm_main.btn_sendClick(Sender: TObject);
begin
  SendStringBuffer.Add(edt_text.Text);
  edt_text.Text:='';
  edt_text.SetFocus;
  try
    ipclient.Addr:=edt_ip1.Text;
    ipclient.Port:=edt_sendport.Text;
    ipclient.Proto:='tcp';
    ipclient.Connect;
  except
    on E: Exception do
    begin
      mmo_nachrichten.Lines.Insert(0, 'Error: '+E.Message);
    end;
  end;
end;

procedure Tfrm_main.btn_startClick(Sender: TObject);
begin
  if btn_start.Caption='Startthen
  begin
    btn_start.Caption:='Stop';
    ipserver.Addr:='0.0.0.0';
    ipserver.Port:=edt_port.Text;
    ipserver.Proto:='tcp';
    ipserver.Listen;
  end else begin
    btn_start.Caption:='Start';
    ipserver.Shutdown(0);
  end;
end;

procedure Tfrm_main.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ipserver.Abort;
end;

procedure Tfrm_main.FormCreate(Sender: TObject);
begin
  SendStringBuffer:=TStringList.Create;
end;

procedure Tfrm_main.FormDestroy(Sender: TObject);
begin
  SendStringBuffer.Free;
end;

procedure Tfrm_main.FormShow(Sender: TObject);
begin
  mmo_nachrichten.Lines.Clear;
  edt_text.Text:='';
  edt_port.Value:=17001;
  edt_sendport.Value:=17001;
end;

procedure Tfrm_main.ipclientSessionClosed(Sender: TObject; ErrCode: Word);
begin
  mmo_nachrichten.Lines.Insert(0, 'Client Session Closed: '+IntToStr(ErrCode));
end;

procedure Tfrm_main.ipclientSessionConnected(Sender: TObject; ErrCode: Word);
begin
  mmo_nachrichten.Lines.Insert(0, 'Client Session Connected');
  while SendStringBuffer.Count>0 do
  begin
      ipclient.SendStr(SendStringBuffer[0]+#13#10);
      mmo_nachrichten.Lines.Insert(0, 'Gesendet: '+SendStringBuffer[0]);
      SendStringBuffer.Delete(0);
  end;
  ipclient.Close;
end;

procedure Tfrm_main.ipserverChangeState(Sender: TObject; OldState,
  NewState: TSocketState);
begin
  case newstate of
    wsInvalidState: mmo_nachrichten.Lines.Insert(0, 'ServerState: Invalid State');
    wsOpened: mmo_nachrichten.Lines.Insert(0, 'ServerState: Öffnet');
    wsBound: mmo_nachrichten.Lines.Insert(0, 'ServerState: Gebunden');
    wsConnecting: mmo_nachrichten.Lines.Insert(0, 'ServerState: Verbinden');
    wsSocksConnected: mmo_nachrichten.Lines.Insert(0, 'ServerState: Socks verbunden');
    wsConnected: mmo_nachrichten.Lines.Insert(0, 'ServerState: Verbunden');
    wsAccepting: mmo_nachrichten.Lines.Insert(0, 'ServerState: Akzeptiert');
    wsListening: mmo_nachrichten.Lines.Insert(0, 'ServerState: Wartet...');
    wsClosed: mmo_nachrichten.Lines.Insert(0, 'ServerState: Geschlossen');
  end;
end;

procedure Tfrm_main.ipserverDataAvailable(Sender: TObject; ErrCode: Word);
var
  s: string;
begin
  mmo_nachrichten.Lines.Insert(0, 'Server: DataAvailable');
  if ErrCode<>0 then Exit;
  s:=ipserver.ReceiveStr;
  mmo_nachrichten.Lines.Insert(0, 'Empfangen: '+s);
end;

procedure Tfrm_main.ipserverSessionAvailable(Sender: TObject; ErrCode: Word);
var
  mysocket: TSocket;
begin
  if ErrCode <> 0 then exit;
  mysocket:=ipserver.Accept;
  ServerSocket:=TWSocket.Create(nil);
  ServerSocket.Dup(mysocket);
  mmo_nachrichten.Lines.Insert(0, 'Server Session Available: '+ServerSocket.PeerPort);
end;

procedure Tfrm_main.ipserverSessionClosed(Sender: TObject; ErrCode: Word);
begin
  mmo_nachrichten.Lines.Insert(0, 'Server Session Closed: '+IntToStr(ErrCode));
end;

procedure Tfrm_main.ipserverSessionConnected(Sender: TObject; ErrCode: Word);
begin
  mmo_nachrichten.Lines.Insert(0, 'Server Session Connected');
end;

end.
Mein Problem ist jetzt, dass er wohl connected und auch sendet, aber das OnDataAvailable von der Server-Komponente wird nie ausgelöst.

Hier mal das Ergebnis im Memo, was ich beim Senden eines Textes erhalte:

Code:
Client Session Closed: 0
Gesendet: TestTestTest
Client Session Connected
Server Session Available: 49946
ServerState: Wartet...
ServerState: Gebunden
Achso: Und ipserver.LineEnd=#13#10 und ipserver.LineMode=True ist gesetzt.
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo

Geändert von Captnemo (16. Jun 2014 um 16:49 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#7

AW: ICS TWSocket Eingehende Verbindung

  Alt 17. Jun 2014, 08:21
Ein neuer Tag, und kaum geht man neu ausgeruht an die Sache heran, fallen einem gleich die Fehler auf
Nun funktioniert's.

Zur Erklärung: Im OnSessionAvailable wird eine neuen Instanz für die ankommende Session erzeugt
Delphi-Quellcode:
procedure Tfrm_main.ipserverSessionAvailable(Sender: TObject; ErrCode: Word);
var
  mysocket: TSocket;
begin
  if ErrCode <> 0 then exit;
  mysocket:=ipserver.Accept;
  ServerSocket:=TWSocket.Create(nil);
  //Da hier einen neue Instanz von TWSocket erzeugt wird,
  //muß natürlich auch das OnDataAvailable-Ereignis zugeordnet werden,
  //da sonst der Datenempfang nicht festgestell werden kann.
  ServerSocket.OnDataAvailable:=ipserverDataAvailable;
  ServerSocket.OnSessionClosed:=ipserverSessionClosed;
  ServerSocket.OnSessionConnected:=ipserverSessionConnected;
  ServerSocket.OnChangeState:=ipserverChangeState;
  //LineMode,IP und Ports übernehme ich von der Komponente, die auf
  //der Form liegt, da ich dort Veränderungen vornehme, wenn nötig.
  ServerSocket.LineMode:=ServerSocket.LineMode;
  ServerSocket.LineEnd:=ServerSocket.LineEnd;
  ServerSocket.LocalAddr:=ipserver.LocalAddr;
  ServerSocket.Port:=ipserver.Port;
  ServerSocket.Proto:=ipserver.Proto;
  ServerSocket.Dup(mysocket);
  Writelog(False, 'Server Session Available: '+ServerSocket.PeerPort);
end;
dieser müssen natürlich die Ereignisse zugewiesen werden. Das war mein Denkfehler, denn ich dachte er übernimmt diese von der Komponente. Aber klar, woher denn auch. Und letztlich ist das natürlich genial, denn in Abhängigkeit der in OnSessionAvailable zur Verfügung stehenden Daten (z.B. Peer-IP) könnte man unterschiedliche Ereignisbehandlungsroutinen und andere Eigenschaften zuweisen.

Danach empfing ich aber leider nur leere Strings.
Auch hier liegt die Erklärung wieder in der Instanz. Da ich zu Anfang die Ereignisprozeduren für OnDataAvailable nur der Komponente auf der Form zugewiesen habe, habe ich mich beim Auswerten des ReceiveStr diesen auch von dieser geholt. Richtigerweise muss man sich die aber von Sender holen, da es sich ja um einen neue Instanz handelt.
Delphi-Quellcode:
procedure Tfrm_main.ipserverDataAvailable(Sender: TObject; ErrCode: Word);
var
  s: string;
begin
  Writelog(False, 'Server: DataAvailable');
  if ErrCode<>0 then Exit;
  //Wichtig: Mit dem Sender arbeiten
  s:=(Sender as TWSocket).ReceiveStr;
  s:=StringReplace(s,(Sender as TWSocket).LineEnd, '', [rfReplaceAll]);
  if s<>'then
  begin
    //Hier den Emfangenen Text auswerten
    Writelog(True, 'Empfangen: '+s);
  end;
end;
Und schon funktioniert es wie gewünscht. Ich habe ein bischen gebraucht, bis dahinter kam, da der Einstieg auf Grund wenig vorhandener Dokumentation schwierig war.

Für alle die es interessiert und die das nachvollziehen wollen, hab ich mal den Source angehängt.
Vielen Danke für eure Unterstützung.
Angehängte Dateien
Dateityp: rar Client.rar (6,1 KB, 10x aufgerufen)
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:25 Uhr.
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