![]() |
ICS TWSocket Eingehende Verbindung
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:
|
AW: ICS TWSocket Eingehende Verbindung
Ist in der Unit WinSock
|
AW: ICS TWSocket Eingehende Verbindung
Dann meckert er bei mir
[dcc32 FEhler] clt_main.pas(118): E2035 Nicht genügend wirkliche Parameter bei dem
Delphi-Quellcode:
mysocket:=accept;
Aber das es im Wiki von ICS so beschrieben steht, dachte ich, dass ich das so verwenden kann. |
AW: ICS TWSocket Eingehende Verbindung
Wo/wie ist denn Accept deklariert?
|
AW: ICS TWSocket Eingehende Verbindung
Ich vermute mal, an dieser Stelle ist TSocket aus der Unit
Delphi-Quellcode:
gemeint.
OverbyteIcsWSocket
|
AW: ICS TWSocket Eingehende Verbindung
ich habe es mal geändert in
Delphi-Quellcode:
und dann klappt es (frag mich aber, wie die das dann mit dem Beispielcode im Wiki geschafft haben).
mysocket:=(sender as TWSocket).Accept;
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:
Mein Problem ist jetzt, dass er wohl connected und auch sendet, aber das OnDataAvailable von der Server-Komponente wird nie ausgelöst.
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='Start' then 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. Hier mal das Ergebnis im Memo, was ich beim Senden eines Textes erhalte:
Code:
Achso: Und ipserver.LineEnd=#13#10 und ipserver.LineMode=True ist gesetzt.
Client Session Closed: 0
Gesendet: TestTestTest Client Session Connected Server Session Available: 49946 ServerState: Wartet... ServerState: Gebunden |
AW: ICS TWSocket Eingehende Verbindung
Liste der Anhänge anzeigen (Anzahl: 1)
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:
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.
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; 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:
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.
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; 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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:10 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