unit Unit38;
interface
uses
Winapi.Windows,
Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs, OverbyteIcsWndControl,
OverbyteIcsWSocket,
Vcl.StdCtrls;
const WM_MEINEMELDUNG = WM_APP + 1;
type
TForm38 =
class(TForm)
SocketA: TWSocket;
ListenSocket: TWSocket;
SocketB: TWSocket;
VerbindeButton: TButton;
SchliessenButton: TButton;
Memo1: TMemo;
SendeString: TButton;
procedure FormCreate(Sender: TObject);
procedure VerbindeButtonClick(Sender: TObject);
procedure ListenSocketSessionAvailable(Sender: TObject; ErrCode: Word);
procedure SocketAChangeState(Sender: TObject; OldState,
NewState: TSocketState);
procedure SchliessenButtonClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
procedure SendeStringClick(Sender: TObject);
procedure SocketBDataAvailable(Sender: TObject; ErrCode: Word);
private
{ Private-Deklarationen }
procedure Machetwas(
var Message: TMessage);
message WM_MEINEMELDUNG;
public
{ Public-Deklarationen }
procedure Verbinde;
end;
var
Form38: TForm38;
implementation
{$R *.dfm}
uses System.TypInfo;
var appschliesst : boolean = false;
function socketstr( hss : TSocketState ) :
string;
begin
{ Wert von hss in String umwandeln }
Result := GetEnumName(typeinfo(TSocketState),ord(hss));
end;
procedure TForm38.Machetwas(
var Message: TMessage);
begin
case Message.WParam
of
0 :
begin
{ Störung simulieren: SocketA oder Gegenstelle SocketB schliessen }
Memo1.Lines.Add('
Entweder SocketA oder SocketB schliessen');
case random(2)
of
0: SocketA.Close;
1: SocketB.Close;
end;
end;
{ SocketA verbindet neu mit der Gegenstelle }
1 : Verbinde;
end;
end;
procedure TForm38.SchliessenButtonClick(Sender: TObject);
begin
PostMessage(
Handle, WM_MEINEMELDUNG, 0, 0 );
end;
procedure TForm38.VerbindeButtonClick(Sender: TObject);
begin
Verbinde;
end;
{ ListenSocket geht in den SocketState wsListening über: }
procedure TForm38.FormCreate(Sender: TObject);
begin
ListenSocket.Addr := '
0.0.0.0';
ListenSocket.Port := '
7001';
ListenSocket.Proto := '
tcp';
ListenSocket.Listen;
ListenSocket.OnChangeState := SocketAChangeState;
SocketA.OnChangeState := SocketAChangeState;
SocketB.OnChangeState := SocketAChangeState;
ListenSocket.OnSessionAvailable := ListenSocketSessionAvailable;
SocketB.OnDataAvailable := SocketBDataAvailable;
end;
{ SocketA soll mit ListenSocket verbinden: }
procedure TForm38.Verbinde;
begin
Memo1.Lines.Add('
SocketA Verbindungsaufbau');
SocketA.Close;
SocketA.Addr := '
127.0.0.1';
SocketA.proto := '
tcp';
SocketA.Port := '
7001';
SocketA.Connect;
end;
{ OnSessionAvailable:
ListenSocket akzeptiert die Verbindung, SocketB übernimmt (Dup) - SocketA und SocketB sind miteinander verbunden }
procedure TForm38.ListenSocketSessionAvailable(Sender: TObject; ErrCode: Word);
var h : THandle;
begin
h := ListenSocket.Accept;
SocketB.Dup( h );
end;
{ ChangeState:
Änderung SocketState }
procedure TForm38.SocketAChangeState(Sender: TObject; OldState,
NewState: TSocketState);
begin
if appschliesst
then
begin
if ( SocketA.State = wsclosed )
and ( SocketB.State = wsClosed )
then close;
end
else
begin
Memo1.Lines.Add( (Sender
as TWSocket).
Name + '
' + socketstr(OldState) + '
->' + socketstr(NewState) );
if ( Sender = SocketA )
then
if ( OldState = wsConnected )
and ( NewState = wsClosed )
then
PostMessage(
Handle, WM_MEINEMELDUNG, 1, 0 );
end;
end;
{ Beispiel: SocketA sendet einen String an SocketB }
procedure TForm38.SendeStringClick(Sender: TObject);
begin
if SocketA.State = wsConnected
then
SocketA.SendStr( Memo1.Text );
end;
{ SockezB empfängt den String}
procedure TForm38.SocketBDataAvailable(Sender: TObject; ErrCode: Word);
var empfangen :
string;
begin
empfangen := SocketB.ReceiveStr;
if empfangen <> '
'
then
ShowMessage( empfangen );
end;
{ Die App soll geschlossen werden...
Wenn SocketA oder SocketB nicht geschlossen sind => canclose:= false =>
Im SocketAChangeState wird Close aufgerufen, sobald SocketA und SocketB geschlossen sind }
procedure TForm38.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin
{.....}
if canclose
then
begin
appschliesst := true;
ListenSocket.Close;
SocketA.CloseDelayed;
SocketB.CloseDelayed;
canclose := ( SocketA.State = wsclosed )
and ( SocketB.State = wsClosed );
end;
end;
end.