diff --git a/Demos/ChatDemo/Client/ChatClient.identcache b/Demos/ChatDemo/Client/ChatClient.identcache
index 99d9dc7..e4ca886 100644
Binary files a/Demos/ChatDemo/Client/ChatClient.identcache and b/Demos/ChatDemo/Client/ChatClient.identcache differ
diff --git a/Demos/ChatDemo/Client/ChatClient.res b/Demos/ChatDemo/Client/ChatClient.res
index d543374..2cc0378 100644
Binary files a/Demos/ChatDemo/Client/ChatClient.res and b/Demos/ChatDemo/Client/ChatClient.res differ
diff --git a/Demos/ChatDemo/Server/ChatServer.identcache b/Demos/ChatDemo/Server/ChatServer.identcache
index 503e9b6..ada193f 100644
Binary files a/Demos/ChatDemo/Server/ChatServer.identcache and b/Demos/ChatDemo/Server/ChatServer.identcache differ
diff --git a/Demos/ChatDemo/Server/ChatServer.res b/Demos/ChatDemo/Server/ChatServer.res
index 2d1e943..f0a2763 100644
Binary files a/Demos/ChatDemo/Server/ChatServer.res and b/Demos/ChatDemo/Server/ChatServer.res differ
diff --git a/Demos/SimpleSockets/Client.identcache b/Demos/SimpleSockets/Client.identcache
deleted file mode 100644
index 8b81f03..0000000
Binary files a/Demos/SimpleSockets/Client.identcache and /dev/null differ
diff --git a/Demos/SimpleSockets/Client.res b/Demos/SimpleSockets/Client.res
deleted file mode 100644
index 3e78508..0000000
Binary files a/Demos/SimpleSockets/Client.res and /dev/null differ
diff --git a/Demos/SimpleSockets/Client.dpr b/Demos/SimpleSockets/Client/Client.dpr
similarity index 94%
rename from Demos/SimpleSockets/Client.dpr
rename to Demos/SimpleSockets/Client/Client.dpr
index 028c5c1..aa89c08 100644
--- a/Demos/SimpleSockets/Client.dpr
+++ b/Demos/SimpleSockets/Client/Client.dpr
@@ -1,17 +1,17 @@
-program Client;
-
-uses
- Vcl.Forms,
- ufrmMain in 'ufrmMain.pas' {Form1};
-
-{$R *.res}
-
-begin
- {$IFDEF DEBUG}
- ReportMemoryLeaksOnShutdown := True;
- {$ENDIF}
- Application.Initialize;
- Application.MainFormOnTaskbar := True;
- Application.CreateForm(TForm1, Form1);
- Application.Run;
-end.
+program Client;
+
+uses
+ Vcl.Forms,
+ ufrmMain in 'ufrmMain.pas' {Form1};
+
+{$R *.res}
+
+begin
+ {$IFDEF DEBUG}
+ ReportMemoryLeaksOnShutdown := True;
+ {$ENDIF}
+ Application.Initialize;
+ Application.MainFormOnTaskbar := True;
+ Application.CreateForm(TForm1, Form1);
+ Application.Run;
+end.
diff --git a/Demos/SimpleSockets/Client.dproj b/Demos/SimpleSockets/Client/Client.dproj
similarity index 98%
rename from Demos/SimpleSockets/Client.dproj
rename to Demos/SimpleSockets/Client/Client.dproj
index 1273313..697cfc6 100644
--- a/Demos/SimpleSockets/Client.dproj
+++ b/Demos/SimpleSockets/Client/Client.dproj
@@ -1,214 +1,216 @@
-
-
- {2F2F33BE-2A99-4B2A-A206-E1E4DE8915A3}
- 18.8
- Client.dpr
- Release
- DCC32
- VCL
- True
- Win64
- 3
- Application
-
-
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Cfg_1
- true
- true
-
-
- true
- Cfg_1
- true
- true
-
-
- true
- Base
- true
-
-
- true
- Cfg_2
- true
- true
-
-
- true
- Cfg_2
- true
- true
-
-
- true
- Cfg_2
- true
- true
-
-
- Client.exe
- off
- vclx;vcl;vclimg;dbrtl;Rave77VCL;bdertl;rtl;vclactnband;xmlrtl;vcldb;vcldbx;vcltouch;dsnap;dsnapcon;TeeUI;TeeDB;Tee;vclib;ibxpress;adortl;IndyCore;IndySystem;IndyProtocols;inet;intrawebdb_100_140;Intraweb_100_140;VclSmp;vclie;websnap;webdsnap;inetdb;inetdbbde;inetdbxpress;soaprtl;vclribbon;dbexpress;DbxCommonDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;DbxClientDriver;DataSnapServer;DBXInterBaseDriver;DBXMySQLDriver;dbxcds;DBXFirebirdDriver;DBXSybaseASEDriver;DBXSybaseASADriver;DBXOracleDriver;DBXMSSQLDriver;DBXInformixDriver;DBXDb2Driver;dclOfficeXP;$(DCC_UsePackage)
- $(BDSCOMMONDIR)\DCP
- $(BDSCOMMONDIR)\DCU
- x86
- 00400000
- Client
- Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)
- true
- 1032
- CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
-
-
- android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar
-
-
- System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
- Debug
- CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
- 1033
- $(BDS)\bin\default_app.manifest
- $(BDS)\bin\delphi_PROJECTICON.ico
- true
- $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
- $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
-
-
- $(BDS)\bin\default_app.manifest
- $(BDS)\bin\delphi_PROJECTICON.ico
- true
- $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
- $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
- System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
- Debug
- CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
- 1033
-
-
- false
- RELEASE;$(DCC_Define)
- 0
- 0
-
-
- true
- PerMonitorV2
-
-
- true
- PerMonitorV2
-
-
- DEBUG;$(DCC_Define)
-
-
- Debug
-
-
- true
- PerMonitorV2
-
-
- true
- PerMonitorV2
- 1033
- CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
-
-
-
- MainSource
-
-
-
-
-
- Cfg_2
- Base
-
-
- Base
-
-
- Cfg_1
- Base
-
-
-
-
- Delphi.Personality.12
-
-
-
-
- Client.dpr
-
-
- False
- True
- False
-
-
- True
- False
- 1
- 0
- 0
- 0
- False
- False
- False
- False
- False
- 1032
- 1253
-
-
-
-
- 1.0.0.0
-
-
-
-
-
- 1.0.0.0
-
-
-
- Microsoft Office 2000 Sample Automation Server Wrapper Components
-
-
-
- False
- True
- True
-
-
- 12
-
-
-
+
+
+ {2F2F33BE-2A99-4B2A-A206-E1E4DE8915A3}
+ 20.2
+ Client.dpr
+ Release
+ DCC32
+ VCL
+ True
+ Win64
+ 3
+ Application
+ Client
+
+
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ Client.exe
+ off
+ vclx;vcl;vclimg;dbrtl;Rave77VCL;bdertl;rtl;vclactnband;xmlrtl;vcldb;vcldbx;vcltouch;dsnap;dsnapcon;TeeUI;TeeDB;Tee;vclib;ibxpress;adortl;IndyCore;IndySystem;IndyProtocols;inet;intrawebdb_100_140;Intraweb_100_140;VclSmp;vclie;websnap;webdsnap;inetdb;inetdbbde;inetdbxpress;soaprtl;vclribbon;dbexpress;DbxCommonDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;DbxClientDriver;DataSnapServer;DBXInterBaseDriver;DBXMySQLDriver;dbxcds;DBXFirebirdDriver;DBXSybaseASEDriver;DBXSybaseASADriver;DBXOracleDriver;DBXMSSQLDriver;DBXInformixDriver;DBXDb2Driver;dclOfficeXP;$(DCC_UsePackage)
+ $(BDSCOMMONDIR)\DCP
+ $(BDSCOMMONDIR)\DCU
+ x86
+ 00400000
+ Client
+ Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)
+ true
+ 1032
+ CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
+
+
+ android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
+
+
+ System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
+ Debug
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
+ 1033
+ $(BDS)\bin\default_app.manifest
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ true
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+
+
+ $(BDS)\bin\default_app.manifest
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ true
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+ System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
+ Debug
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+ 1033
+
+
+ false
+ RELEASE;$(DCC_Define)
+ 0
+ 0
+
+
+ true
+ PerMonitorV2
+
+
+ true
+ PerMonitorV2
+
+
+ DEBUG;$(DCC_Define)
+
+
+ Debug
+
+
+ true
+ PerMonitorV2
+
+
+ true
+ PerMonitorV2
+ 1033
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+
+
+
+ MainSource
+
+
+
+
+
+ Base
+
+
+ Cfg_1
+ Base
+
+
+ Cfg_2
+ Base
+
+
+
+
+ Delphi.Personality.12
+
+
+
+
+ Client.dpr
+
+
+ False
+ True
+ False
+
+
+ True
+ False
+ 1
+ 0
+ 0
+ 0
+ False
+ False
+ False
+ False
+ False
+ 1032
+ 1253
+
+
+
+
+ 1.0.0.0
+
+
+
+
+
+ 1.0.0.0
+
+
+
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+
+
+
+ False
+ True
+ True
+
+
+ 12
+
+
+
diff --git a/Demos/SimpleSockets/Client.dproj.local b/Demos/SimpleSockets/Client/Client.dproj.local
similarity index 96%
rename from Demos/SimpleSockets/Client.dproj.local
rename to Demos/SimpleSockets/Client/Client.dproj.local
index b4899b3..d8869d4 100644
--- a/Demos/SimpleSockets/Client.dproj.local
+++ b/Demos/SimpleSockets/Client/Client.dproj.local
@@ -1,6 +1,6 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/Demos/SimpleSockets/Client.dsk b/Demos/SimpleSockets/Client/Client.dsk
similarity index 94%
rename from Demos/SimpleSockets/Client.dsk
rename to Demos/SimpleSockets/Client/Client.dsk
index 50e13fa..38e48cb 100644
--- a/Demos/SimpleSockets/Client.dsk
+++ b/Demos/SimpleSockets/Client/Client.dsk
@@ -1,769 +1,769 @@
-[Closed Files]
-File_0=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\SOURCE\VCL\Vcl.Forms.pas',0,1,1,6,10,0,0,{{1755,4}
-File_1=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas',0,1,9,1,59,0,0,,
-File_2=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpDXAPIHelpers.pas',0,1,1,1,5,0,0,,{1
-File_3=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncThreads.pas',0,1,88,13,95,0,0,,
-File_4=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpDXAPI.pas',0,1,1,1,1,0,0,,{1
-File_5=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectX9\uD3DX9.pas',0,1,5404,1,5435,0,0,,
-File_6=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectX9\uDirect3D9.pas',0,1,3093,1,3112,0,0,,
-File_7=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpTypes.pas',0,1,404,1,417,0,0,,
-File_8=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpDirectPanel.pas',0,1,2514,5,2533,0,0,,{1
-File_9=TSourceModule,'c:\program files (x86)\embarcadero\rad studio\7.0\SOURCE\WIN32\VCL\Forms.pas',0,1,9739,51,9749,0,0,,
-
-[Modules]
-Module0=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\ufrmMain.pas
-Module1=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Client.dproj
-Count=2
-EditWindowCount=1
-
-[C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\ufrmMain.pas]
-ModuleType=TSourceModule
-
-[C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Client.dproj]
-ModuleType=TBaseProject
-
-[EditWindow0]
-ViewCount=2
-CurrentEditView=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\ufrmMain.pas
-View0=0
-View1=1
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=9900
-Height=8837
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=9900
-ClientHeight=8837
-DockedToMainForm=1
-BorlandEditorCodeExplorer=BorlandEditorCodeExplorer@EditWindow0
-TopPanelSize=0
-LeftPanelSize=1894
-LeftPanelClients=PropertyInspector,DockSite3
-LeftPanelData=000008000101000000008E120000000000000166070000000000000100000000530E000009000000446F636B53697465330100000000FC2000001100000050726F7065727479496E73706563746F72FFFFFFFF
-RightPanelSize=1525
-RightPanelClients=DockSite2,DockSite4
-RightPanelData=000008000101000000008E1200000000000001F50500000000000001000000004612000009000000446F636B53697465320100000000FC20000009000000446F636B5369746534FFFFFFFF
-BottomPanelSize=0
-BottomPanelClients=DockSite1,MessageView
-BottomPanelData=0000080001020200000009000000446F636B53697465310F0000004D65737361676556696577466F726D1534000000000000022A06000000000000FFFFFFFF
-BottomMiddlePanelSize=0
-BottomMiddlePanelClients=DockSite0,GraphDrawingModel
-BottomMiddelPanelData=0000080001020200000009000000446F636B536974653010000000477261706844726177696E67566965779A1D00000000000002F206000000000000FFFFFFFF
-
-[View0]
-CustomEditViewType=TEditView
-Module=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Client.dpr
-CursorX=11
-CursorY=12
-TopLine=1
-LeftCol=1
-Elisions=
-Bookmarks=
-EditViewName=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Client.dpr
-
-[View1]
-CustomEditViewType=TEditView
-Module=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\ufrmMain.pas
-CursorX=35
-CursorY=130
-TopLine=118
-LeftCol=1
-Elisions=
-Bookmarks=
-EditViewName=Borland.FormDesignerView
-
-[UndockedDesigner]
-Count=0
-
-[Watches]
-Count=0
-
-[WatchWindow]
-WatchColumnWidth=120
-WatchShowColumnHeaders=1
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=3825
-Height=1093
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1093
-TBDockHeight=209
-LRDockWidth=13600
-Dockable=1
-StayOnTop=0
-
-[Breakpoints]
-Count=1
-Breakpoint0='C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncSources.pas',973,'',0,1,'',1,0,0,'',1,'','','',0,''
-
-[EmbarcaderoWin32Debugger_AddressBreakpoints]
-Count=0
-
-[EmbarcaderoWin64Debugger_AddressBreakpoints]
-Count=0
-
-[EmbarcaderoAndroid32Debugger_AddressBreakpoints]
-Count=0
-
-[EmbarcaderoAndroid64Debugger_AddressBreakpoints]
-Count=0
-
-[Main Window]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=0
-State=2
-Left=144
-Top=279
-Width=8931
-Height=8523
-MaxLeft=-6
-MaxTop=-12
-MaxWidth=8931
-MaxHeight=8523
-ClientWidth=10025
-ClientHeight=9744
-BottomPanelSize=8444
-BottomPanelClients=EditWindow0
-BottomPanelData=0000080000000000000000000000000000000000000000000000000100000000000000000C0000004564697457696E646F775F30FFFFFFFF
-
-[ProjectManager]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=1525
-Height=4151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=4151
-TBDockHeight=5895
-LRDockWidth=2350
-Dockable=1
-StayOnTop=0
-
-[MessageView]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2769
-Height=1419
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2769
-ClientHeight=1419
-TBDockHeight=1419
-LRDockWidth=2769
-Dockable=1
-StayOnTop=0
-
-[ToolForm]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=1525
-Height=3616
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=3616
-TBDockHeight=7151
-LRDockWidth=2000
-Dockable=1
-StayOnTop=0
-
-[ClipboardHistory]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=0
-State=0
-Left=0
-Top=0
-Width=2338
-Height=5174
-MaxLeft=-6
-MaxTop=-12
-ClientWidth=2262
-ClientHeight=4733
-TBDockHeight=5174
-LRDockWidth=2338
-Dockable=1
-StayOnTop=0
-
-[PropertyInspector]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=358
-Width=1894
-Height=4674
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1894
-ClientHeight=4674
-TBDockHeight=9012
-LRDockWidth=1894
-Dockable=1
-StayOnTop=0
-SplitPos=111
-
-[PropInspDesignerSelection]
-ArrangeBy=Name
-SelectedItem=Action,
-ExpandedItems=LiveBindings=0,"LiveBindings Designer=0",Margins=0,ActiveControl=0,Anchors=0,BorderIcons=0
-
-[frmDesignPreview]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=1525
-Height=4151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=4151
-TBDockHeight=5953
-LRDockWidth=2512
-Dockable=1
-StayOnTop=0
-
-[TemplateView]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=1
-State=0
-Left=0
-Top=0
-Width=275
-Height=360
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=275
-ClientHeight=360
-TBDockHeight=360
-LRDockWidth=275
-Dockable=1
-StayOnTop=0
-Name=120
-Description=334
-filter=1
-
-[DebugLogView]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=3825
-Height=1093
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1093
-TBDockHeight=407
-LRDockWidth=4950
-Dockable=1
-StayOnTop=0
-
-[ThreadStatusWindow]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=3825
-Height=1093
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1093
-TBDockHeight=209
-LRDockWidth=7406
-Dockable=1
-StayOnTop=0
-Column0Width=145
-Column1Width=100
-Column2Width=115
-Column3Width=252
-
-[LocalVarsWindow]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=3825
-Height=1093
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1093
-TBDockHeight=1535
-LRDockWidth=3481
-Dockable=1
-StayOnTop=0
-
-[CallStackWindow]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=3825
-Height=1093
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1093
-TBDockHeight=2070
-LRDockWidth=3481
-Dockable=1
-StayOnTop=0
-
-[PatchForm]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2338
-Height=1151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1151
-TBDockHeight=2500
-LRDockWidth=3400
-Dockable=1
-StayOnTop=0
-
-[FindReferencsForm]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2338
-Height=1151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1151
-TBDockHeight=2314
-LRDockWidth=2825
-Dockable=1
-StayOnTop=0
-
-[RefactoringForm]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2338
-Height=1151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1151
-TBDockHeight=3209
-LRDockWidth=2825
-Dockable=1
-StayOnTop=0
-
-[ToDo List]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2338
-Height=1140
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1140
-TBDockHeight=1151
-LRDockWidth=3675
-Dockable=1
-StayOnTop=0
-Column0Width=314
-Column1Width=30
-Column2Width=150
-Column3Width=172
-Column4Width=129
-SortOrder=4
-ShowHints=1
-ShowChecked=1
-
-[DataExplorerContainer]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=1525
-Height=4151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=4151
-TBDockHeight=4884
-LRDockWidth=7150
-Dockable=1
-StayOnTop=0
-
-[GraphDrawingModel]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2856
-Height=3209
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2856
-ClientHeight=3209
-TBDockHeight=3209
-LRDockWidth=2856
-Dockable=1
-StayOnTop=0
-
-[ClassBrowserTool]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=1
-State=0
-Left=-318
-Top=-363
-Width=1850
-Height=3140
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1850
-ClientHeight=3140
-TBDockHeight=3140
-LRDockWidth=1850
-Dockable=1
-StayOnTop=0
-
-[MetricsView]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2338
-Height=1163
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1163
-TBDockHeight=4837
-LRDockWidth=3562
-Dockable=1
-StayOnTop=0
-
-[QAView]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2338
-Height=1163
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1163
-TBDockHeight=4837
-LRDockWidth=3562
-Dockable=1
-StayOnTop=0
-
-[BreakpointWindow]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=3825
-Height=1093
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1093
-TBDockHeight=1547
-LRDockWidth=8744
-Dockable=1
-StayOnTop=0
-Column0Width=200
-Column1Width=75
-Column2Width=200
-Column3Width=200
-Column4Width=200
-Column5Width=75
-Column6Width=75
-
-[StructureView]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=1894
-Height=3419
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1894
-ClientHeight=3419
-TBDockHeight=3674
-LRDockWidth=1894
-Dockable=1
-StayOnTop=0
-
-[fmGrepResults]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=0
-State=0
-Left=0
-Top=0
-Width=2575
-Height=4372
-MaxLeft=-6
-MaxTop=-12
-ClientWidth=2475
-ClientHeight=3919
-TBDockHeight=4372
-LRDockWidth=2575
-Dockable=1
-StayOnTop=0
-
-[ModelViewTool]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=1525
-Height=4151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=4151
-TBDockHeight=4884
-LRDockWidth=5306
-Dockable=1
-StayOnTop=0
-
-[BorlandEditorCodeExplorer@EditWindow0]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=0
-State=0
-Left=0
-Top=0
-Width=1825
-Height=6174
-MaxLeft=-6
-MaxTop=-12
-ClientWidth=1725
-ClientHeight=5721
-TBDockHeight=6174
-LRDockWidth=1825
-Dockable=1
-StayOnTop=0
-
-[DockHosts]
-DockHostCount=5
-
-[DockSite0]
-HostDockSite=DockBottomCenterPanel
-DockSiteType=1
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=1
-State=0
-Left=8
-Top=8
-Width=2338
-Height=1477
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1477
-TBDockHeight=1477
-LRDockWidth=2338
-Dockable=1
-StayOnTop=0
-TabPosition=1
-ActiveTabID=RefactoringForm
-TabDockClients=RefactoringForm,PatchForm,FindReferencsForm,ToDo List,MetricsView,QAView
-
-[DockSite1]
-HostDockSite=DockBottomPanel
-DockSiteType=1
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=1
-State=0
-Left=8
-Top=8
-Width=3825
-Height=1419
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1419
-TBDockHeight=1419
-LRDockWidth=3825
-Dockable=1
-StayOnTop=0
-TabPosition=1
-ActiveTabID=DebugLogView
-TabDockClients=DebugLogView,BreakpointWindow,ThreadStatusWindow,CallStackWindow,WatchWindow,LocalVarsWindow
-
-[DockSite2]
-HostDockSite=DockRightPanel
-DockSiteType=1
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=28
-Width=1525
-Height=4477
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=4477
-TBDockHeight=9012
-LRDockWidth=1525
-Dockable=1
-StayOnTop=0
-TabPosition=1
-ActiveTabID=ProjectManager
-TabDockClients=ProjectManager,ModelViewTool,DataExplorerContainer,frmDesignPreview
-
-[DockSite3]
-HostDockSite=DockLeftPanel
-DockSiteType=1
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=28
-Width=1894
-Height=3419
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1894
-ClientHeight=3419
-TBDockHeight=9012
-LRDockWidth=1894
-Dockable=1
-StayOnTop=0
-TabPosition=1
-ActiveTabID=StructureView
-TabDockClients=StructureView,ClassBrowserTool
-
-[DockSite4]
-HostDockSite=DockRightPanel
-DockSiteType=1
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=449
-Width=1525
-Height=3616
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=3616
-TBDockHeight=9012
-LRDockWidth=1525
-Dockable=1
-StayOnTop=0
-TabPosition=1
-ActiveTabID=ToolForm
-TabDockClients=ToolForm,TemplateView
-
+[Closed Files]
+File_0=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\SOURCE\VCL\Vcl.Forms.pas',0,1,1,6,10,0,0,{{1755,4}
+File_1=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas',0,1,9,1,59,0,0,,
+File_2=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpDXAPIHelpers.pas',0,1,1,1,5,0,0,,{1
+File_3=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncThreads.pas',0,1,88,13,95,0,0,,
+File_4=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpDXAPI.pas',0,1,1,1,1,0,0,,{1
+File_5=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectX9\uD3DX9.pas',0,1,5404,1,5435,0,0,,
+File_6=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectX9\uDirect3D9.pas',0,1,3093,1,3112,0,0,,
+File_7=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpTypes.pas',0,1,404,1,417,0,0,,
+File_8=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpDirectPanel.pas',0,1,2514,5,2533,0,0,,{1
+File_9=TSourceModule,'c:\program files (x86)\embarcadero\rad studio\7.0\SOURCE\WIN32\VCL\Forms.pas',0,1,9739,51,9749,0,0,,
+
+[Modules]
+Module0=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\ufrmMain.pas
+Module1=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Client.dproj
+Count=2
+EditWindowCount=1
+
+[C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\ufrmMain.pas]
+ModuleType=TSourceModule
+
+[C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Client.dproj]
+ModuleType=TBaseProject
+
+[EditWindow0]
+ViewCount=2
+CurrentEditView=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\ufrmMain.pas
+View0=0
+View1=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=9900
+Height=8837
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=9900
+ClientHeight=8837
+DockedToMainForm=1
+BorlandEditorCodeExplorer=BorlandEditorCodeExplorer@EditWindow0
+TopPanelSize=0
+LeftPanelSize=1894
+LeftPanelClients=PropertyInspector,DockSite3
+LeftPanelData=000008000101000000008E120000000000000166070000000000000100000000530E000009000000446F636B53697465330100000000FC2000001100000050726F7065727479496E73706563746F72FFFFFFFF
+RightPanelSize=1525
+RightPanelClients=DockSite2,DockSite4
+RightPanelData=000008000101000000008E1200000000000001F50500000000000001000000004612000009000000446F636B53697465320100000000FC20000009000000446F636B5369746534FFFFFFFF
+BottomPanelSize=0
+BottomPanelClients=DockSite1,MessageView
+BottomPanelData=0000080001020200000009000000446F636B53697465310F0000004D65737361676556696577466F726D1534000000000000022A06000000000000FFFFFFFF
+BottomMiddlePanelSize=0
+BottomMiddlePanelClients=DockSite0,GraphDrawingModel
+BottomMiddelPanelData=0000080001020200000009000000446F636B536974653010000000477261706844726177696E67566965779A1D00000000000002F206000000000000FFFFFFFF
+
+[View0]
+CustomEditViewType=TEditView
+Module=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Client.dpr
+CursorX=11
+CursorY=12
+TopLine=1
+LeftCol=1
+Elisions=
+Bookmarks=
+EditViewName=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Client.dpr
+
+[View1]
+CustomEditViewType=TEditView
+Module=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\ufrmMain.pas
+CursorX=35
+CursorY=130
+TopLine=118
+LeftCol=1
+Elisions=
+Bookmarks=
+EditViewName=Borland.FormDesignerView
+
+[UndockedDesigner]
+Count=0
+
+[Watches]
+Count=0
+
+[WatchWindow]
+WatchColumnWidth=120
+WatchShowColumnHeaders=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=209
+LRDockWidth=13600
+Dockable=1
+StayOnTop=0
+
+[Breakpoints]
+Count=1
+Breakpoint0='C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncSources.pas',973,'',0,1,'',1,0,0,'',1,'','','',0,''
+
+[EmbarcaderoWin32Debugger_AddressBreakpoints]
+Count=0
+
+[EmbarcaderoWin64Debugger_AddressBreakpoints]
+Count=0
+
+[EmbarcaderoAndroid32Debugger_AddressBreakpoints]
+Count=0
+
+[EmbarcaderoAndroid64Debugger_AddressBreakpoints]
+Count=0
+
+[Main Window]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=0
+State=2
+Left=144
+Top=279
+Width=8931
+Height=8523
+MaxLeft=-6
+MaxTop=-12
+MaxWidth=8931
+MaxHeight=8523
+ClientWidth=10025
+ClientHeight=9744
+BottomPanelSize=8444
+BottomPanelClients=EditWindow0
+BottomPanelData=0000080000000000000000000000000000000000000000000000000100000000000000000C0000004564697457696E646F775F30FFFFFFFF
+
+[ProjectManager]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=5895
+LRDockWidth=2350
+Dockable=1
+StayOnTop=0
+
+[MessageView]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2769
+Height=1419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2769
+ClientHeight=1419
+TBDockHeight=1419
+LRDockWidth=2769
+Dockable=1
+StayOnTop=0
+
+[ToolForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=3616
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=3616
+TBDockHeight=7151
+LRDockWidth=2000
+Dockable=1
+StayOnTop=0
+
+[ClipboardHistory]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=0
+State=0
+Left=0
+Top=0
+Width=2338
+Height=5174
+MaxLeft=-6
+MaxTop=-12
+ClientWidth=2262
+ClientHeight=4733
+TBDockHeight=5174
+LRDockWidth=2338
+Dockable=1
+StayOnTop=0
+
+[PropertyInspector]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=358
+Width=1894
+Height=4674
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1894
+ClientHeight=4674
+TBDockHeight=9012
+LRDockWidth=1894
+Dockable=1
+StayOnTop=0
+SplitPos=111
+
+[PropInspDesignerSelection]
+ArrangeBy=Name
+SelectedItem=Action,
+ExpandedItems=LiveBindings=0,"LiveBindings Designer=0",Margins=0,ActiveControl=0,Anchors=0,BorderIcons=0
+
+[frmDesignPreview]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=5953
+LRDockWidth=2512
+Dockable=1
+StayOnTop=0
+
+[TemplateView]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=0
+Top=0
+Width=275
+Height=360
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=275
+ClientHeight=360
+TBDockHeight=360
+LRDockWidth=275
+Dockable=1
+StayOnTop=0
+Name=120
+Description=334
+filter=1
+
+[DebugLogView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=407
+LRDockWidth=4950
+Dockable=1
+StayOnTop=0
+
+[ThreadStatusWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=209
+LRDockWidth=7406
+Dockable=1
+StayOnTop=0
+Column0Width=145
+Column1Width=100
+Column2Width=115
+Column3Width=252
+
+[LocalVarsWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=1535
+LRDockWidth=3481
+Dockable=1
+StayOnTop=0
+
+[CallStackWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=2070
+LRDockWidth=3481
+Dockable=1
+StayOnTop=0
+
+[PatchForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1151
+TBDockHeight=2500
+LRDockWidth=3400
+Dockable=1
+StayOnTop=0
+
+[FindReferencsForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1151
+TBDockHeight=2314
+LRDockWidth=2825
+Dockable=1
+StayOnTop=0
+
+[RefactoringForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1151
+TBDockHeight=3209
+LRDockWidth=2825
+Dockable=1
+StayOnTop=0
+
+[ToDo List]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1140
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1140
+TBDockHeight=1151
+LRDockWidth=3675
+Dockable=1
+StayOnTop=0
+Column0Width=314
+Column1Width=30
+Column2Width=150
+Column3Width=172
+Column4Width=129
+SortOrder=4
+ShowHints=1
+ShowChecked=1
+
+[DataExplorerContainer]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=4884
+LRDockWidth=7150
+Dockable=1
+StayOnTop=0
+
+[GraphDrawingModel]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2856
+Height=3209
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2856
+ClientHeight=3209
+TBDockHeight=3209
+LRDockWidth=2856
+Dockable=1
+StayOnTop=0
+
+[ClassBrowserTool]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=-318
+Top=-363
+Width=1850
+Height=3140
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1850
+ClientHeight=3140
+TBDockHeight=3140
+LRDockWidth=1850
+Dockable=1
+StayOnTop=0
+
+[MetricsView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1163
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1163
+TBDockHeight=4837
+LRDockWidth=3562
+Dockable=1
+StayOnTop=0
+
+[QAView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1163
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1163
+TBDockHeight=4837
+LRDockWidth=3562
+Dockable=1
+StayOnTop=0
+
+[BreakpointWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=1547
+LRDockWidth=8744
+Dockable=1
+StayOnTop=0
+Column0Width=200
+Column1Width=75
+Column2Width=200
+Column3Width=200
+Column4Width=200
+Column5Width=75
+Column6Width=75
+
+[StructureView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1894
+Height=3419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1894
+ClientHeight=3419
+TBDockHeight=3674
+LRDockWidth=1894
+Dockable=1
+StayOnTop=0
+
+[fmGrepResults]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=0
+State=0
+Left=0
+Top=0
+Width=2575
+Height=4372
+MaxLeft=-6
+MaxTop=-12
+ClientWidth=2475
+ClientHeight=3919
+TBDockHeight=4372
+LRDockWidth=2575
+Dockable=1
+StayOnTop=0
+
+[ModelViewTool]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=4884
+LRDockWidth=5306
+Dockable=1
+StayOnTop=0
+
+[BorlandEditorCodeExplorer@EditWindow0]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=0
+State=0
+Left=0
+Top=0
+Width=1825
+Height=6174
+MaxLeft=-6
+MaxTop=-12
+ClientWidth=1725
+ClientHeight=5721
+TBDockHeight=6174
+LRDockWidth=1825
+Dockable=1
+StayOnTop=0
+
+[DockHosts]
+DockHostCount=5
+
+[DockSite0]
+HostDockSite=DockBottomCenterPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=8
+Top=8
+Width=2338
+Height=1477
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1477
+TBDockHeight=1477
+LRDockWidth=2338
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=RefactoringForm
+TabDockClients=RefactoringForm,PatchForm,FindReferencsForm,ToDo List,MetricsView,QAView
+
+[DockSite1]
+HostDockSite=DockBottomPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=8
+Top=8
+Width=3825
+Height=1419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1419
+TBDockHeight=1419
+LRDockWidth=3825
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=DebugLogView
+TabDockClients=DebugLogView,BreakpointWindow,ThreadStatusWindow,CallStackWindow,WatchWindow,LocalVarsWindow
+
+[DockSite2]
+HostDockSite=DockRightPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=28
+Width=1525
+Height=4477
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4477
+TBDockHeight=9012
+LRDockWidth=1525
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=ProjectManager
+TabDockClients=ProjectManager,ModelViewTool,DataExplorerContainer,frmDesignPreview
+
+[DockSite3]
+HostDockSite=DockLeftPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=28
+Width=1894
+Height=3419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1894
+ClientHeight=3419
+TBDockHeight=9012
+LRDockWidth=1894
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=StructureView
+TabDockClients=StructureView,ClassBrowserTool
+
+[DockSite4]
+HostDockSite=DockRightPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=449
+Width=1525
+Height=3616
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=3616
+TBDockHeight=9012
+LRDockWidth=1525
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=ToolForm
+TabDockClients=ToolForm,TemplateView
+
diff --git a/Demos/SimpleSockets/Client/Client.identcache b/Demos/SimpleSockets/Client/Client.identcache
new file mode 100644
index 0000000..113ce2c
Binary files /dev/null and b/Demos/SimpleSockets/Client/Client.identcache differ
diff --git a/Demos/SimpleSockets/Client/Client.res b/Demos/SimpleSockets/Client/Client.res
new file mode 100644
index 0000000..d4b6e46
Binary files /dev/null and b/Demos/SimpleSockets/Client/Client.res differ
diff --git a/Demos/SimpleSockets/Client.skincfg b/Demos/SimpleSockets/Client/Client.skincfg
similarity index 94%
rename from Demos/SimpleSockets/Client.skincfg
rename to Demos/SimpleSockets/Client/Client.skincfg
index 9e7a05b..0f00ce7 100644
--- a/Demos/SimpleSockets/Client.skincfg
+++ b/Demos/SimpleSockets/Client/Client.skincfg
@@ -1,33 +1,33 @@
-[ExpressSkins]
-Default=1
-ShowNotifications=1
-Enabled=1
-dxSkinBlack=1
-dxSkinBlue=0
-dxSkinCaramel=0
-dxSkinCoffee=0
-dxSkinDarkRoom=0
-dxSkinDarkSide=1
-dxSkinFoggy=0
-dxSkinGlassOceans=0
-dxSkiniMaginary=0
-dxSkinLilian=0
-dxSkinLiquidSky=0
-dxSkinLondonLiquidSky=0
-dxSkinMcSkin=0
-dxSkinMoneyTwins=0
-dxSkinOffice2007Black=1
-dxSkinOffice2007Blue=0
-dxSkinOffice2007Green=0
-dxSkinOffice2007Pink=0
-dxSkinOffice2007Silver=1
-dxSkinPumpkin=0
-dxSkinSeven=0
-dxSkinSharp=0
-dxSkinSilver=0
-dxSkinSpringTime=0
-dxSkinStardust=0
-dxSkinSummer2008=0
-dxSkinsDefaultPainters=0
-dxSkinValentine=0
-dxSkinXmas2008Blue=0
+[ExpressSkins]
+Default=1
+ShowNotifications=1
+Enabled=1
+dxSkinBlack=1
+dxSkinBlue=0
+dxSkinCaramel=0
+dxSkinCoffee=0
+dxSkinDarkRoom=0
+dxSkinDarkSide=1
+dxSkinFoggy=0
+dxSkinGlassOceans=0
+dxSkiniMaginary=0
+dxSkinLilian=0
+dxSkinLiquidSky=0
+dxSkinLondonLiquidSky=0
+dxSkinMcSkin=0
+dxSkinMoneyTwins=0
+dxSkinOffice2007Black=1
+dxSkinOffice2007Blue=0
+dxSkinOffice2007Green=0
+dxSkinOffice2007Pink=0
+dxSkinOffice2007Silver=1
+dxSkinPumpkin=0
+dxSkinSeven=0
+dxSkinSharp=0
+dxSkinSilver=0
+dxSkinSpringTime=0
+dxSkinStardust=0
+dxSkinSummer2008=0
+dxSkinsDefaultPainters=0
+dxSkinValentine=0
+dxSkinXmas2008Blue=0
diff --git a/Demos/SimpleSockets/Client_Icon.ico b/Demos/SimpleSockets/Client/Client_Icon.ico
similarity index 100%
rename from Demos/SimpleSockets/Client_Icon.ico
rename to Demos/SimpleSockets/Client/Client_Icon.ico
diff --git a/Demos/SimpleSockets/ufrmMain.dfm b/Demos/SimpleSockets/Client/ufrmMain.dfm
similarity index 91%
rename from Demos/SimpleSockets/ufrmMain.dfm
rename to Demos/SimpleSockets/Client/ufrmMain.dfm
index adf35a8..cc47e35 100644
--- a/Demos/SimpleSockets/ufrmMain.dfm
+++ b/Demos/SimpleSockets/Client/ufrmMain.dfm
@@ -1,174 +1,172 @@
-object Form1: TForm1
- Left = 0
- Top = 0
- ActiveControl = edtDataToSend
- Caption = 'TCPClient'
- ClientHeight = 243
- ClientWidth = 527
- Color = clBtnFace
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- OldCreateOrder = False
- Position = poScreenCenter
- OnDestroy = FormDestroy
- PixelsPerInch = 96
- TextHeight = 13
- object memLog: TMemo
- AlignWithMargins = True
- Left = 5
- Top = 37
- Width = 517
- Height = 169
- Margins.Left = 5
- Margins.Top = 0
- Margins.Right = 5
- Margins.Bottom = 5
- Align = alClient
- ReadOnly = True
- ScrollBars = ssVertical
- TabOrder = 1
- end
- object pnlToolbar: TPanel
- Left = 0
- Top = 0
- Width = 527
- Height = 37
- Align = alTop
- BevelOuter = bvNone
- FullRepaint = False
- TabOrder = 0
- object btnActivate: TButton
- AlignWithMargins = True
- Left = 5
- Top = 5
- Width = 105
- Height = 27
- Margins.Left = 5
- Margins.Top = 5
- Margins.Right = 0
- Margins.Bottom = 5
- Align = alLeft
- Caption = 'Activate'
- TabOrder = 0
- OnClick = btnActivateClick
- end
- object pnlAddress: TPanel
- AlignWithMargins = True
- Left = 110
- Top = 3
- Width = 417
- Height = 31
- Margins.Left = 0
- Margins.Right = 0
- Align = alClient
- BevelOuter = bvNone
- FullRepaint = False
- TabOrder = 1
- object edtHost: TEdit
- AlignWithMargins = True
- Left = 5
- Top = 5
- Width = 281
- Height = 21
- Margins.Left = 5
- Margins.Top = 5
- Margins.Right = 5
- Margins.Bottom = 5
- Align = alClient
- TabOrder = 0
- Text = 'LocalHost'
- TextHint = 'Enter host address'
- OnChange = edtHostChange
- end
- object edtPort: TSpinEdit
- AlignWithMargins = True
- Left = 291
- Top = 5
- Width = 121
- Height = 22
- Margins.Left = 0
- Margins.Top = 5
- Margins.Right = 5
- Margins.Bottom = 5
- Align = alRight
- MaxValue = 0
- MinValue = 0
- TabOrder = 1
- Value = 16233
- OnChange = edtPortChange
- end
- end
- end
- object Panel1: TPanel
- Left = 0
- Top = 211
- Width = 527
- Height = 32
- Margins.Left = 5
- Margins.Top = 0
- Margins.Right = 5
- Margins.Bottom = 5
- Align = alBottom
- BevelOuter = bvNone
- FullRepaint = False
- TabOrder = 2
- object btnSendData: TButton
- AlignWithMargins = True
- Left = 5
- Top = 0
- Width = 105
- Height = 27
- Margins.Left = 5
- Margins.Top = 0
- Margins.Right = 0
- Margins.Bottom = 5
- Align = alLeft
- Caption = 'Send'
- Default = True
- TabOrder = 0
- OnClick = btnSendDataClick
- end
- object Panel2: TPanel
- AlignWithMargins = True
- Left = 110
- Top = 3
- Width = 417
- Height = 26
- Margins.Left = 0
- Margins.Right = 0
- Align = alClient
- BevelOuter = bvNone
- FullRepaint = False
- TabOrder = 1
- object edtDataToSend: TEdit
- AlignWithMargins = True
- Left = 5
- Top = 0
- Width = 407
- Height = 21
- Margins.Left = 5
- Margins.Top = 0
- Margins.Right = 5
- Margins.Bottom = 5
- Align = alClient
- TabOrder = 0
- Text = 'This is some text data'
- TextHint = 'Enter data to send here'
- OnEnter = edtDataToSendEnter
- OnExit = edtDataToSendExit
- end
- end
- end
- object TCPClient: TncTCPClient
- Host = 'localhost'
- OnConnected = TCPClientConnected
- OnDisconnected = TCPClientDisconnected
- OnReadData = TCPClientReadData
- OnReconnected = TCPClientReconnected
- Left = 92
- Top = 52
- end
-end
+object Form1: TForm1
+ Left = 0
+ Top = 0
+ ActiveControl = edtDataToSend
+ Caption = 'TCPClient'
+ ClientHeight = 243
+ ClientWidth = 527
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ Position = poScreenCenter
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ TextHeight = 13
+ object memLog: TMemo
+ AlignWithMargins = True
+ Left = 5
+ Top = 37
+ Width = 517
+ Height = 169
+ Margins.Left = 5
+ Margins.Top = 0
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alClient
+ ReadOnly = True
+ ScrollBars = ssVertical
+ TabOrder = 1
+ OnKeyDown = memLogKeyDown
+ end
+ object pnlToolbar: TPanel
+ Left = 0
+ Top = 0
+ Width = 527
+ Height = 37
+ Align = alTop
+ BevelOuter = bvNone
+ FullRepaint = False
+ TabOrder = 0
+ object btnActivate: TButton
+ AlignWithMargins = True
+ Left = 5
+ Top = 5
+ Width = 105
+ Height = 27
+ Margins.Left = 5
+ Margins.Top = 5
+ Margins.Right = 0
+ Margins.Bottom = 5
+ Align = alLeft
+ Caption = 'Start TCP Client'
+ TabOrder = 0
+ OnClick = btnActivateClick
+ end
+ object pnlAddress: TPanel
+ AlignWithMargins = True
+ Left = 110
+ Top = 3
+ Width = 417
+ Height = 31
+ Margins.Left = 0
+ Margins.Right = 0
+ Align = alClient
+ BevelOuter = bvNone
+ FullRepaint = False
+ TabOrder = 1
+ object edtHost: TEdit
+ AlignWithMargins = True
+ Left = 5
+ Top = 5
+ Width = 281
+ Height = 21
+ Margins.Left = 5
+ Margins.Top = 5
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alClient
+ TabOrder = 0
+ TextHint = 'Enter host address'
+ OnChange = edtHostChange
+ end
+ object edtPort: TSpinEdit
+ AlignWithMargins = True
+ Left = 291
+ Top = 5
+ Width = 121
+ Height = 22
+ Margins.Left = 0
+ Margins.Top = 5
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alRight
+ MaxValue = 0
+ MinValue = 0
+ TabOrder = 1
+ Value = 16233
+ OnChange = edtPortChange
+ end
+ end
+ end
+ object Panel1: TPanel
+ Left = 0
+ Top = 211
+ Width = 527
+ Height = 32
+ Margins.Left = 5
+ Margins.Top = 0
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alBottom
+ BevelOuter = bvNone
+ FullRepaint = False
+ TabOrder = 2
+ object btnSendData: TButton
+ AlignWithMargins = True
+ Left = 5
+ Top = 0
+ Width = 105
+ Height = 27
+ Margins.Left = 5
+ Margins.Top = 0
+ Margins.Right = 0
+ Margins.Bottom = 5
+ Align = alLeft
+ Caption = 'Send'
+ Default = True
+ TabOrder = 0
+ OnClick = btnSendDataClick
+ end
+ object Panel2: TPanel
+ AlignWithMargins = True
+ Left = 110
+ Top = 3
+ Width = 417
+ Height = 26
+ Margins.Left = 0
+ Margins.Right = 0
+ Align = alClient
+ BevelOuter = bvNone
+ FullRepaint = False
+ TabOrder = 1
+ object edtDataToSend: TEdit
+ AlignWithMargins = True
+ Left = 5
+ Top = 0
+ Width = 407
+ Height = 21
+ Margins.Left = 5
+ Margins.Top = 0
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alClient
+ TabOrder = 0
+ Text = 'This is some text data'
+ TextHint = 'Enter data to send here'
+ OnEnter = edtDataToSendEnter
+ OnExit = edtDataToSendExit
+ end
+ end
+ end
+ object TCPClient: TncTCPClient
+ OnConnected = TCPClientConnected
+ OnDisconnected = TCPClientDisconnected
+ OnReadData = TCPClientReadData
+ OnReconnected = TCPClientReconnected
+ Left = 208
+ Top = 80
+ end
+end
diff --git a/Demos/SimpleSockets/Client/ufrmMain.pas b/Demos/SimpleSockets/Client/ufrmMain.pas
new file mode 100644
index 0000000..ba225fb
--- /dev/null
+++ b/Demos/SimpleSockets/Client/ufrmMain.pas
@@ -0,0 +1,233 @@
+unit ufrmMain;
+
+interface
+
+uses
+{$IFDEF MSWINDOWS}
+ WinApi.Windows, WinApi.Winsock2,
+{$ELSE}
+ Posix.SysSocket, Posix.Unistd,
+{$ENDIF}
+ System.Classes, System.SysUtils, Vcl.Forms, Vcl.Controls, Vcl.StdCtrls,
+ Vcl.ExtCtrls, Vcl.Samples.Spin,
+ System.Diagnostics, ncLines, ncSockets;
+
+type
+ TForm1 = class(TForm)
+ memLog: TMemo;
+ pnlToolbar: TPanel;
+ btnActivate: TButton;
+ pnlAddress: TPanel;
+ edtHost: TEdit;
+ edtPort: TSpinEdit;
+ Panel1: TPanel;
+ btnSendData: TButton;
+ Panel2: TPanel;
+ edtDataToSend: TEdit;
+ TCPClient: TncTCPClient;
+ procedure btnActivateClick(Sender: TObject);
+ procedure FormDestroy(Sender: TObject);
+ procedure TCPClientConnected(Sender: TObject; aLine: TncLine);
+ procedure TCPClientDisconnected(Sender: TObject; aLine: TncLine);
+ procedure TCPClientReconnected(Sender: TObject; aLine: TncLine);
+ procedure edtHostChange(Sender: TObject);
+ procedure edtPortChange(Sender: TObject);
+ procedure btnSendDataClick(Sender: TObject);
+ procedure edtDataToSendEnter(Sender: TObject);
+ procedure edtDataToSendExit(Sender: TObject);
+ procedure TCPClientReadData(Sender: TObject; aLine: TncLine;
+ const aBuf: TBytes; aBufCount: Integer);
+ procedure Log(const AMessage: string);
+ procedure memLogKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
+ procedure FormCreate(Sender: TObject);
+ private
+ public
+ end;
+
+var
+ Form1: TForm1;
+
+implementation
+
+{$R *.dfm}
+
+procedure TForm1.FormCreate(Sender: TObject);
+begin
+//
+end;
+
+procedure TForm1.FormDestroy(Sender: TObject);
+begin
+ TCPClient.Active := False;
+end;
+
+// *****************************************************************************
+// Start/Stop Main CLient
+// *****************************************************************************
+procedure TForm1.btnActivateClick(Sender: TObject);
+begin
+ if TCPClient.Active then
+ begin
+ // Deactivate the TCP client
+ TCPClient.Active := False;
+ btnActivate.Caption := 'Start TCP Client';
+ Log('TCP Client Deactivated');
+ end
+ else
+ begin
+ // Check if the host field is blank
+ if Trim(edtHost.Text) = '' then
+ begin
+ Log('Host field cannot be blank.');
+ Exit; // Exit the procedure if the host field is blank
+ end;
+
+ try
+ // Set the host from the text field
+ TCPClient.Host := edtHost.Text;
+
+ // Activate the TCP client
+ TCPClient.Active := True;
+ btnActivate.Caption := 'Stop TCP Client';
+ Log('TCP Client Activated');
+ except
+ on E: Exception do
+ Log('Failed to activate TCP Client: ' + E.Message);
+ end;
+ end;
+end;
+
+// *****************************************************************************
+// Change host (server)
+// *****************************************************************************
+procedure TForm1.edtHostChange(Sender: TObject);
+begin
+ try
+ TCPClient.Host := edtHost.Text;
+ except
+ edtHost.OnChange := nil;
+ try
+ edtHost.Text := TCPClient.Host;
+ finally
+ edtHost.OnChange := edtHostChange;
+ end;
+ raise;
+ end;
+end;
+
+// *****************************************************************************
+// Change Main Client port
+// *****************************************************************************
+procedure TForm1.edtPortChange(Sender: TObject);
+begin
+ try
+ TCPClient.Port := edtPort.Value;
+ except
+ edtPort.OnChange := nil;
+ try
+ edtPort.Value := TCPClient.Port;
+ finally
+ edtPort.OnChange := edtPortChange;
+ end;
+ raise;
+ end;
+end;
+
+// *****************************************************************************
+// Data to send
+// *****************************************************************************
+procedure TForm1.edtDataToSendEnter(Sender: TObject);
+begin
+ btnSendData.Default := True;
+end;
+
+procedure TForm1.edtDataToSendExit(Sender: TObject);
+begin
+ btnSendData.Default := False;
+end;
+
+procedure TForm1.btnSendDataClick(Sender: TObject);
+begin
+ // Check if the data field is blank
+ if Trim(edtDataToSend.Text) = '' then
+ begin
+ Log('Cannot send - Data field cannot be blank.');
+ Exit; // Exit the procedure if the data field is blank
+ end;
+
+ try
+ // Send the data
+ TCPClient.Send(edtDataToSend.Text);
+ Log('Data sent: ' + edtDataToSend.Text);
+ except
+ on E: Exception do
+ Log('Failed to send data: ' + E.Message);
+ end;
+end;
+
+// *****************************************************************************
+// TCPClientConnected
+// *****************************************************************************
+procedure TForm1.TCPClientConnected(Sender: TObject; aLine: TncLine);
+begin
+ Log('Connected');
+ btnActivate.Caption := 'Deactivate';
+end;
+
+// *****************************************************************************
+// TCPClientDisconnected
+// *****************************************************************************
+procedure TForm1.TCPClientDisconnected(Sender: TObject; aLine: TncLine);
+begin
+ Log('Disconnected');
+ btnActivate.Caption := 'Activate';
+end;
+
+// *****************************************************************************
+// TCPClientReconnected
+// *****************************************************************************
+procedure TForm1.TCPClientReconnected(Sender: TObject; aLine: TncLine);
+begin
+ Log('Reconnected');
+end;
+
+// *****************************************************************************
+// Read Data
+// *****************************************************************************
+procedure TForm1.TCPClientReadData(Sender: TObject; aLine: TncLine;
+ const aBuf: TBytes; aBufCount: Integer);
+var
+ BytesReceived: TBytes;
+begin
+ BytesReceived := Copy(aBuf, 0, aBufCount);
+
+ Log('Received: ' + StringOf(BytesReceived));
+
+end;
+
+// *****************************************************************************
+// Memo Log
+// *****************************************************************************
+procedure TForm1.Log(const AMessage: string);
+begin
+ TThread.Queue(nil,
+ procedure
+ begin
+ try
+ memLog.Lines.Add(Format('[%s] %s', [FormatDateTime('hh:nn:ss.zzz', Now),
+ AMessage]));
+ finally
+ end;
+ end);
+end;
+
+procedure TForm1.memLogKeyDown(Sender: TObject; var Key: Word;
+Shift: TShiftState);
+begin
+ if (Shift = [ssCtrl]) and (Key = Ord('A')) then
+ memLog.SelectAll
+ else if (Shift = [ssCtrl]) and (Key = Ord('C')) then
+ memLog.CopyToClipboard;
+end;
+
+end.
diff --git a/Demos/SimpleSockets/Server/Server.dpr b/Demos/SimpleSockets/Server/Server.dpr
new file mode 100644
index 0000000..63d6f38
--- /dev/null
+++ b/Demos/SimpleSockets/Server/Server.dpr
@@ -0,0 +1,17 @@
+program Server;
+
+uses
+ Vcl.Forms,
+ ufrmMain in 'ufrmMain.pas' {Form1};
+
+{$R *.res}
+
+begin
+ {$IFDEF DEBUG}
+ ReportMemoryLeaksOnShutdown := True;
+ {$ENDIF}
+ Application.Initialize;
+ Application.MainFormOnTaskbar := True;
+ Application.CreateForm(TForm1, Form1);
+ Application.Run;
+end.
diff --git a/Demos/SimpleSockets/Srv/Server.dproj b/Demos/SimpleSockets/Server/Server.dproj
similarity index 97%
rename from Demos/SimpleSockets/Srv/Server.dproj
rename to Demos/SimpleSockets/Server/Server.dproj
index 4fcb55a..2019830 100644
--- a/Demos/SimpleSockets/Srv/Server.dproj
+++ b/Demos/SimpleSockets/Server/Server.dproj
@@ -1,216 +1,218 @@
-
-
- {B76A70BC-BC2B-42B3-990D-FEC6939EAFD9}
- 18.8
- Server.dpr
- Release
- DCC32
- VCL
- True
- Win64
- 3
- Application
-
-
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Cfg_1
- true
- true
-
-
- true
- Cfg_1
- true
- true
-
-
- true
- Base
- true
-
-
- true
- Cfg_2
- true
- true
-
-
- true
- Cfg_2
- true
- true
-
-
- true
- Cfg_2
- true
- true
-
-
- Server.exe
- off
- vclx;vcl;vclimg;dbrtl;Rave77VCL;bdertl;rtl;vclactnband;xmlrtl;vcldb;vcldbx;vcltouch;dsnap;dsnapcon;TeeUI;TeeDB;Tee;vclib;ibxpress;adortl;IndyCore;IndySystem;IndyProtocols;inet;intrawebdb_100_140;Intraweb_100_140;VclSmp;vclie;websnap;webdsnap;inetdb;inetdbbde;inetdbxpress;soaprtl;vclribbon;dbexpress;DbxCommonDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;DbxClientDriver;DataSnapServer;DBXInterBaseDriver;DBXMySQLDriver;dbxcds;DBXFirebirdDriver;DBXSybaseASEDriver;DBXSybaseASADriver;DBXOracleDriver;DBXMSSQLDriver;DBXInformixDriver;DBXDb2Driver;dclOfficeXP;$(DCC_UsePackage)
- $(BDSCOMMONDIR)\DCP
- $(BDSCOMMONDIR)\DCU
- x86
- 00400000
- Server
- Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)
- true
- 1032
- CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
-
-
- android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar
-
-
- System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
- Debug
- CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
- 1033
- $(BDS)\bin\default_app.manifest
- $(BDS)\bin\delphi_PROJECTICON.ico
- true
- $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
- $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
-
-
- $(BDS)\bin\default_app.manifest
- $(BDS)\bin\delphi_PROJECTICON.ico
- true
- $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
- $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
- System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
- Debug
- CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
- 1033
-
-
- false
- RELEASE;$(DCC_Define)
- 0
- 0
-
-
- true
- PerMonitorV2
-
-
- true
- PerMonitorV2
- 1033
- CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
- $(BDS)\bin\delphi_PROJECTICON.ico
-
-
- false
- DEBUG;$(DCC_Define)
-
-
- Debug
-
-
- true
- PerMonitorV2
-
-
- true
- PerMonitorV2
-
-
-
- MainSource
-
-
-
-
-
- Cfg_2
- Base
-
-
- Base
-
-
- Cfg_1
- Base
-
-
-
-
- Delphi.Personality.12
-
-
-
-
- False
- True
- False
-
-
- True
- False
- 1
- 0
- 0
- 0
- False
- False
- False
- False
- False
- 1032
- 1253
-
-
-
-
- 1.0.0.0
-
-
-
-
-
- 1.0.0.0
-
-
-
- Microsoft Office 2000 Sample Automation Server Wrapper Components
-
-
- Server.dpr
-
-
-
- False
- True
- True
-
-
- 12
-
-
-
+
+
+ {B76A70BC-BC2B-42B3-990D-FEC6939EAFD9}
+ 20.2
+ Server.dpr
+ Release
+ DCC32
+ VCL
+ True
+ Win64
+ 3
+ Application
+ Server
+
+
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ Server.exe
+ off
+ vclx;vcl;vclimg;dbrtl;Rave77VCL;bdertl;rtl;vclactnband;xmlrtl;vcldb;vcldbx;vcltouch;dsnap;dsnapcon;TeeUI;TeeDB;Tee;vclib;ibxpress;adortl;IndyCore;IndySystem;IndyProtocols;inet;intrawebdb_100_140;Intraweb_100_140;VclSmp;vclie;websnap;webdsnap;inetdb;inetdbbde;inetdbxpress;soaprtl;vclribbon;dbexpress;DbxCommonDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;DbxClientDriver;DataSnapServer;DBXInterBaseDriver;DBXMySQLDriver;dbxcds;DBXFirebirdDriver;DBXSybaseASEDriver;DBXSybaseASADriver;DBXOracleDriver;DBXMSSQLDriver;DBXInformixDriver;DBXDb2Driver;dclOfficeXP;$(DCC_UsePackage)
+ $(BDSCOMMONDIR)\DCP
+ $(BDSCOMMONDIR)\DCU
+ x86
+ 00400000
+ Server
+ Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)
+ true
+ 1032
+ CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
+
+
+ android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
+
+
+ System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
+ Debug
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
+ 1033
+ $(BDS)\bin\default_app.manifest
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ true
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+
+
+ $(BDS)\bin\default_app.manifest
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ true
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+ System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
+ Debug
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+ 1033
+
+
+ false
+ RELEASE;$(DCC_Define)
+ 0
+ 0
+
+
+ true
+ PerMonitorV2
+
+
+ true
+ PerMonitorV2
+ 1033
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+ $(BDS)\bin\delphi_PROJECTICON.ico
+
+
+ false
+ DEBUG;$(DCC_Define)
+
+
+ Debug
+
+
+ true
+ PerMonitorV2
+
+
+ true
+ PerMonitorV2
+
+
+
+ MainSource
+
+
+
+
+
+ Base
+
+
+ Cfg_1
+ Base
+
+
+ Cfg_2
+ Base
+
+
+
+
+ Delphi.Personality.12
+
+
+
+
+ False
+ True
+ False
+
+
+ True
+ False
+ 1
+ 0
+ 0
+ 0
+ False
+ False
+ False
+ False
+ False
+ 1032
+ 1253
+
+
+
+
+ 1.0.0.0
+
+
+
+
+
+ 1.0.0.0
+
+
+
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+
+
+ Server.dpr
+
+
+
+ False
+ True
+ True
+
+
+ 12
+
+
+
diff --git a/Demos/SimpleSockets/Srv/Server.dproj.local b/Demos/SimpleSockets/Server/Server.dproj.local
similarity index 96%
rename from Demos/SimpleSockets/Srv/Server.dproj.local
rename to Demos/SimpleSockets/Server/Server.dproj.local
index b4899b3..d8869d4 100644
--- a/Demos/SimpleSockets/Srv/Server.dproj.local
+++ b/Demos/SimpleSockets/Server/Server.dproj.local
@@ -1,6 +1,6 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/Demos/SimpleSockets/Srv/Server.dsk b/Demos/SimpleSockets/Server/Server.dsk
similarity index 94%
rename from Demos/SimpleSockets/Srv/Server.dsk
rename to Demos/SimpleSockets/Server/Server.dsk
index 1fc1133..78670b2 100644
--- a/Demos/SimpleSockets/Srv/Server.dsk
+++ b/Demos/SimpleSockets/Server/Server.dsk
@@ -1,768 +1,768 @@
-[Closed Files]
-File_0=TSourceModule,'C:\Users\Programmer\Documents\Development\Components\NetCom7\Source\ncSockets.pas',0,1,1081,1,1097,0,0,,
-File_1=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\SOURCE\VCL\Vcl.Forms.pas',0,1,1,15,10,0,0,{{1755,4}
-File_2=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\SOURCE\VCL\Vcl.StdCtrls.pas',0,1,1,6,10,0,0,{{1657,4}
-File_3=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\source\rtl\common\System.Classes.pas',0,1,1,6,10,0,0,,
-File_4=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\SOURCE\RTL\SYS\System.SysUtils.pas',0,1,1,6,16,0,0,,
-File_5=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\source\rtl\win\Winapi.Messages.pas',0,1,1,6,19,0,0,,
-File_6=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncSockets.pas',0,1,1241,1,1260,0,0,,{1
-File_7=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncSources.pas',0,1,738,3,762,0,0,,{1
-File_8=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpDXAPIHelpers.pas',0,1,1,1,5,0,0,,{1
-File_9=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncThreads.pas',0,1,88,13,95,0,0,,
-
-[Modules]
-Module0=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas
-Module1=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\Server.dproj
-Count=2
-EditWindowCount=1
-
-[C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas]
-ModuleType=TSourceModule
-
-[C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\Server.dproj]
-ModuleType=TBaseProject
-
-[EditWindow0]
-ViewCount=2
-CurrentEditView=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas
-View0=0
-View1=1
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=9900
-Height=8837
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=9900
-ClientHeight=8837
-DockedToMainForm=1
-BorlandEditorCodeExplorer=BorlandEditorCodeExplorer@EditWindow0
-TopPanelSize=0
-LeftPanelSize=1894
-LeftPanelClients=PropertyInspector,DockSite3
-LeftPanelData=000008000101000000008E120000000000000166070000000000000100000000530E000009000000446F636B53697465330100000000FC2000001100000050726F7065727479496E73706563746F72FFFFFFFF
-RightPanelSize=1525
-RightPanelClients=DockSite2,DockSite4
-RightPanelData=000008000101000000008E1200000000000001F50500000000000001000000004612000009000000446F636B53697465320100000000FC20000009000000446F636B5369746534FFFFFFFF
-BottomPanelSize=0
-BottomPanelClients=DockSite1,MessageView
-BottomPanelData=0000080001020200000009000000446F636B53697465310F0000004D65737361676556696577466F726D1534000000000000022A06000000000000FFFFFFFF
-BottomMiddlePanelSize=0
-BottomMiddlePanelClients=DockSite0,GraphDrawingModel
-BottomMiddelPanelData=0000080001020200000009000000446F636B536974653010000000477261706844726177696E67566965779A1D00000000000002F206000000000000FFFFFFFF
-
-[View0]
-CustomEditViewType=TEditView
-Module=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\Server.dpr
-CursorX=20
-CursorY=5
-TopLine=1
-LeftCol=1
-Elisions=
-Bookmarks=
-EditViewName=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\Server.dpr
-
-[View1]
-CustomEditViewType=TEditView
-Module=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas
-CursorX=11
-CursorY=6
-TopLine=1
-LeftCol=1
-Elisions=
-Bookmarks=
-EditViewName=Borland.FormDesignerView
-
-[UndockedDesigner]
-Count=0
-
-[Watches]
-Count=0
-
-[WatchWindow]
-WatchColumnWidth=120
-WatchShowColumnHeaders=1
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=3825
-Height=1093
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1093
-TBDockHeight=209
-LRDockWidth=13600
-Dockable=1
-StayOnTop=0
-
-[Breakpoints]
-Count=0
-
-[EmbarcaderoWin32Debugger_AddressBreakpoints]
-Count=0
-
-[EmbarcaderoWin64Debugger_AddressBreakpoints]
-Count=0
-
-[EmbarcaderoAndroid32Debugger_AddressBreakpoints]
-Count=0
-
-[EmbarcaderoAndroid64Debugger_AddressBreakpoints]
-Count=0
-
-[Main Window]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=0
-State=2
-Left=144
-Top=279
-Width=8931
-Height=8523
-MaxLeft=-6
-MaxTop=-12
-MaxWidth=8931
-MaxHeight=8523
-ClientWidth=10025
-ClientHeight=9744
-BottomPanelSize=8444
-BottomPanelClients=EditWindow0
-BottomPanelData=0000080000000000000000000000000000000000000000000000000100000000000000000C0000004564697457696E646F775F30FFFFFFFF
-
-[ProjectManager]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=1525
-Height=4151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=4151
-TBDockHeight=5895
-LRDockWidth=2350
-Dockable=1
-StayOnTop=0
-
-[MessageView]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2769
-Height=1419
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2769
-ClientHeight=1419
-TBDockHeight=1419
-LRDockWidth=2769
-Dockable=1
-StayOnTop=0
-
-[ToolForm]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=1525
-Height=3616
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=3616
-TBDockHeight=7151
-LRDockWidth=2000
-Dockable=1
-StayOnTop=0
-
-[ClipboardHistory]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=0
-State=0
-Left=0
-Top=0
-Width=2338
-Height=5174
-MaxLeft=-6
-MaxTop=-12
-ClientWidth=2262
-ClientHeight=4733
-TBDockHeight=5174
-LRDockWidth=2338
-Dockable=1
-StayOnTop=0
-
-[PropertyInspector]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=358
-Width=1894
-Height=4674
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1894
-ClientHeight=4674
-TBDockHeight=9012
-LRDockWidth=1894
-Dockable=1
-StayOnTop=0
-SplitPos=111
-
-[PropInspDesignerSelection]
-ArrangeBy=Name
-SelectedItem=Action,
-ExpandedItems=LiveBindings=0,"LiveBindings Designer=0",Margins=0,ActiveControl=0,Anchors=0,BorderIcons=0
-
-[frmDesignPreview]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=1525
-Height=4151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=4151
-TBDockHeight=5953
-LRDockWidth=2512
-Dockable=1
-StayOnTop=0
-
-[TemplateView]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=1
-State=0
-Left=0
-Top=0
-Width=275
-Height=360
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=275
-ClientHeight=360
-TBDockHeight=360
-LRDockWidth=275
-Dockable=1
-StayOnTop=0
-Name=120
-Description=334
-filter=1
-
-[DebugLogView]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=3825
-Height=1093
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1093
-TBDockHeight=407
-LRDockWidth=4950
-Dockable=1
-StayOnTop=0
-
-[ThreadStatusWindow]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=3825
-Height=1093
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1093
-TBDockHeight=209
-LRDockWidth=7406
-Dockable=1
-StayOnTop=0
-Column0Width=145
-Column1Width=100
-Column2Width=115
-Column3Width=252
-
-[LocalVarsWindow]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=3825
-Height=1093
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1093
-TBDockHeight=1535
-LRDockWidth=3481
-Dockable=1
-StayOnTop=0
-
-[CallStackWindow]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=3825
-Height=1093
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1093
-TBDockHeight=2070
-LRDockWidth=3481
-Dockable=1
-StayOnTop=0
-
-[PatchForm]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2338
-Height=1151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1151
-TBDockHeight=2500
-LRDockWidth=3400
-Dockable=1
-StayOnTop=0
-
-[FindReferencsForm]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2338
-Height=1151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1151
-TBDockHeight=2314
-LRDockWidth=2825
-Dockable=1
-StayOnTop=0
-
-[RefactoringForm]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2338
-Height=1151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1151
-TBDockHeight=3209
-LRDockWidth=2825
-Dockable=1
-StayOnTop=0
-
-[ToDo List]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2338
-Height=1140
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1140
-TBDockHeight=1151
-LRDockWidth=3675
-Dockable=1
-StayOnTop=0
-Column0Width=314
-Column1Width=30
-Column2Width=150
-Column3Width=172
-Column4Width=129
-SortOrder=4
-ShowHints=1
-ShowChecked=1
-
-[DataExplorerContainer]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=1525
-Height=4151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=4151
-TBDockHeight=4884
-LRDockWidth=7150
-Dockable=1
-StayOnTop=0
-
-[GraphDrawingModel]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2856
-Height=3209
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2856
-ClientHeight=3209
-TBDockHeight=3209
-LRDockWidth=2856
-Dockable=1
-StayOnTop=0
-
-[ClassBrowserTool]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=1
-State=0
-Left=-318
-Top=-363
-Width=1850
-Height=3140
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1850
-ClientHeight=3140
-TBDockHeight=3140
-LRDockWidth=1850
-Dockable=1
-StayOnTop=0
-
-[MetricsView]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2338
-Height=1163
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1163
-TBDockHeight=4837
-LRDockWidth=3562
-Dockable=1
-StayOnTop=0
-
-[QAView]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=2338
-Height=1163
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1163
-TBDockHeight=4837
-LRDockWidth=3562
-Dockable=1
-StayOnTop=0
-
-[BreakpointWindow]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=3825
-Height=1093
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1093
-TBDockHeight=1547
-LRDockWidth=8744
-Dockable=1
-StayOnTop=0
-Column0Width=200
-Column1Width=75
-Column2Width=200
-Column3Width=200
-Column4Width=200
-Column5Width=75
-Column6Width=75
-
-[StructureView]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=1894
-Height=3419
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1894
-ClientHeight=3419
-TBDockHeight=3674
-LRDockWidth=1894
-Dockable=1
-StayOnTop=0
-
-[fmGrepResults]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=0
-State=0
-Left=0
-Top=0
-Width=2575
-Height=4372
-MaxLeft=-6
-MaxTop=-12
-ClientWidth=2475
-ClientHeight=3919
-TBDockHeight=4372
-LRDockWidth=2575
-Dockable=1
-StayOnTop=0
-
-[ModelViewTool]
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=0
-Width=1525
-Height=4151
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=4151
-TBDockHeight=4884
-LRDockWidth=5306
-Dockable=1
-StayOnTop=0
-
-[BorlandEditorCodeExplorer@EditWindow0]
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=0
-State=0
-Left=0
-Top=0
-Width=1825
-Height=6174
-MaxLeft=-6
-MaxTop=-12
-ClientWidth=1725
-ClientHeight=5721
-TBDockHeight=6174
-LRDockWidth=1825
-Dockable=1
-StayOnTop=0
-
-[DockHosts]
-DockHostCount=5
-
-[DockSite0]
-HostDockSite=DockBottomCenterPanel
-DockSiteType=1
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=1
-State=0
-Left=8
-Top=8
-Width=2338
-Height=1477
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=2338
-ClientHeight=1477
-TBDockHeight=1477
-LRDockWidth=2338
-Dockable=1
-StayOnTop=0
-TabPosition=1
-ActiveTabID=RefactoringForm
-TabDockClients=RefactoringForm,PatchForm,FindReferencsForm,ToDo List,MetricsView,QAView
-
-[DockSite1]
-HostDockSite=DockBottomPanel
-DockSiteType=1
-PercentageSizes=1
-Create=1
-Visible=0
-Docked=1
-State=0
-Left=8
-Top=8
-Width=3825
-Height=1419
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=3825
-ClientHeight=1419
-TBDockHeight=1419
-LRDockWidth=3825
-Dockable=1
-StayOnTop=0
-TabPosition=1
-ActiveTabID=DebugLogView
-TabDockClients=DebugLogView,BreakpointWindow,ThreadStatusWindow,CallStackWindow,WatchWindow,LocalVarsWindow
-
-[DockSite2]
-HostDockSite=DockRightPanel
-DockSiteType=1
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=28
-Width=1525
-Height=4477
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=4477
-TBDockHeight=9012
-LRDockWidth=1525
-Dockable=1
-StayOnTop=0
-TabPosition=1
-ActiveTabID=ProjectManager
-TabDockClients=ProjectManager,ModelViewTool,DataExplorerContainer,frmDesignPreview
-
-[DockSite3]
-HostDockSite=DockLeftPanel
-DockSiteType=1
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=28
-Width=1894
-Height=3419
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1894
-ClientHeight=3419
-TBDockHeight=9012
-LRDockWidth=1894
-Dockable=1
-StayOnTop=0
-TabPosition=1
-ActiveTabID=StructureView
-TabDockClients=StructureView,ClassBrowserTool
-
-[DockSite4]
-HostDockSite=DockRightPanel
-DockSiteType=1
-PercentageSizes=1
-Create=1
-Visible=1
-Docked=1
-State=0
-Left=0
-Top=449
-Width=1525
-Height=3616
-MaxLeft=-1
-MaxTop=-1
-ClientWidth=1525
-ClientHeight=3616
-TBDockHeight=9012
-LRDockWidth=1525
-Dockable=1
-StayOnTop=0
-TabPosition=1
-ActiveTabID=ToolForm
-TabDockClients=ToolForm,TemplateView
-
+[Closed Files]
+File_0=TSourceModule,'C:\Users\Programmer\Documents\Development\Components\NetCom7\Source\ncSockets.pas',0,1,1081,1,1097,0,0,,
+File_1=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\SOURCE\VCL\Vcl.Forms.pas',0,1,1,15,10,0,0,{{1755,4}
+File_2=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\SOURCE\VCL\Vcl.StdCtrls.pas',0,1,1,6,10,0,0,{{1657,4}
+File_3=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\source\rtl\common\System.Classes.pas',0,1,1,6,10,0,0,,
+File_4=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\SOURCE\RTL\SYS\System.SysUtils.pas',0,1,1,6,16,0,0,,
+File_5=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\source\rtl\win\Winapi.Messages.pas',0,1,1,6,19,0,0,,
+File_6=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncSockets.pas',0,1,1241,1,1260,0,0,,{1
+File_7=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncSources.pas',0,1,738,3,762,0,0,,{1
+File_8=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpDXAPIHelpers.pas',0,1,1,1,5,0,0,,{1
+File_9=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncThreads.pas',0,1,88,13,95,0,0,,
+
+[Modules]
+Module0=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas
+Module1=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\Server.dproj
+Count=2
+EditWindowCount=1
+
+[C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas]
+ModuleType=TSourceModule
+
+[C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\Server.dproj]
+ModuleType=TBaseProject
+
+[EditWindow0]
+ViewCount=2
+CurrentEditView=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas
+View0=0
+View1=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=9900
+Height=8837
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=9900
+ClientHeight=8837
+DockedToMainForm=1
+BorlandEditorCodeExplorer=BorlandEditorCodeExplorer@EditWindow0
+TopPanelSize=0
+LeftPanelSize=1894
+LeftPanelClients=PropertyInspector,DockSite3
+LeftPanelData=000008000101000000008E120000000000000166070000000000000100000000530E000009000000446F636B53697465330100000000FC2000001100000050726F7065727479496E73706563746F72FFFFFFFF
+RightPanelSize=1525
+RightPanelClients=DockSite2,DockSite4
+RightPanelData=000008000101000000008E1200000000000001F50500000000000001000000004612000009000000446F636B53697465320100000000FC20000009000000446F636B5369746534FFFFFFFF
+BottomPanelSize=0
+BottomPanelClients=DockSite1,MessageView
+BottomPanelData=0000080001020200000009000000446F636B53697465310F0000004D65737361676556696577466F726D1534000000000000022A06000000000000FFFFFFFF
+BottomMiddlePanelSize=0
+BottomMiddlePanelClients=DockSite0,GraphDrawingModel
+BottomMiddelPanelData=0000080001020200000009000000446F636B536974653010000000477261706844726177696E67566965779A1D00000000000002F206000000000000FFFFFFFF
+
+[View0]
+CustomEditViewType=TEditView
+Module=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\Server.dpr
+CursorX=20
+CursorY=5
+TopLine=1
+LeftCol=1
+Elisions=
+Bookmarks=
+EditViewName=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\Server.dpr
+
+[View1]
+CustomEditViewType=TEditView
+Module=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas
+CursorX=11
+CursorY=6
+TopLine=1
+LeftCol=1
+Elisions=
+Bookmarks=
+EditViewName=Borland.FormDesignerView
+
+[UndockedDesigner]
+Count=0
+
+[Watches]
+Count=0
+
+[WatchWindow]
+WatchColumnWidth=120
+WatchShowColumnHeaders=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=209
+LRDockWidth=13600
+Dockable=1
+StayOnTop=0
+
+[Breakpoints]
+Count=0
+
+[EmbarcaderoWin32Debugger_AddressBreakpoints]
+Count=0
+
+[EmbarcaderoWin64Debugger_AddressBreakpoints]
+Count=0
+
+[EmbarcaderoAndroid32Debugger_AddressBreakpoints]
+Count=0
+
+[EmbarcaderoAndroid64Debugger_AddressBreakpoints]
+Count=0
+
+[Main Window]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=0
+State=2
+Left=144
+Top=279
+Width=8931
+Height=8523
+MaxLeft=-6
+MaxTop=-12
+MaxWidth=8931
+MaxHeight=8523
+ClientWidth=10025
+ClientHeight=9744
+BottomPanelSize=8444
+BottomPanelClients=EditWindow0
+BottomPanelData=0000080000000000000000000000000000000000000000000000000100000000000000000C0000004564697457696E646F775F30FFFFFFFF
+
+[ProjectManager]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=5895
+LRDockWidth=2350
+Dockable=1
+StayOnTop=0
+
+[MessageView]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2769
+Height=1419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2769
+ClientHeight=1419
+TBDockHeight=1419
+LRDockWidth=2769
+Dockable=1
+StayOnTop=0
+
+[ToolForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=3616
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=3616
+TBDockHeight=7151
+LRDockWidth=2000
+Dockable=1
+StayOnTop=0
+
+[ClipboardHistory]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=0
+State=0
+Left=0
+Top=0
+Width=2338
+Height=5174
+MaxLeft=-6
+MaxTop=-12
+ClientWidth=2262
+ClientHeight=4733
+TBDockHeight=5174
+LRDockWidth=2338
+Dockable=1
+StayOnTop=0
+
+[PropertyInspector]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=358
+Width=1894
+Height=4674
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1894
+ClientHeight=4674
+TBDockHeight=9012
+LRDockWidth=1894
+Dockable=1
+StayOnTop=0
+SplitPos=111
+
+[PropInspDesignerSelection]
+ArrangeBy=Name
+SelectedItem=Action,
+ExpandedItems=LiveBindings=0,"LiveBindings Designer=0",Margins=0,ActiveControl=0,Anchors=0,BorderIcons=0
+
+[frmDesignPreview]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=5953
+LRDockWidth=2512
+Dockable=1
+StayOnTop=0
+
+[TemplateView]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=0
+Top=0
+Width=275
+Height=360
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=275
+ClientHeight=360
+TBDockHeight=360
+LRDockWidth=275
+Dockable=1
+StayOnTop=0
+Name=120
+Description=334
+filter=1
+
+[DebugLogView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=407
+LRDockWidth=4950
+Dockable=1
+StayOnTop=0
+
+[ThreadStatusWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=209
+LRDockWidth=7406
+Dockable=1
+StayOnTop=0
+Column0Width=145
+Column1Width=100
+Column2Width=115
+Column3Width=252
+
+[LocalVarsWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=1535
+LRDockWidth=3481
+Dockable=1
+StayOnTop=0
+
+[CallStackWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=2070
+LRDockWidth=3481
+Dockable=1
+StayOnTop=0
+
+[PatchForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1151
+TBDockHeight=2500
+LRDockWidth=3400
+Dockable=1
+StayOnTop=0
+
+[FindReferencsForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1151
+TBDockHeight=2314
+LRDockWidth=2825
+Dockable=1
+StayOnTop=0
+
+[RefactoringForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1151
+TBDockHeight=3209
+LRDockWidth=2825
+Dockable=1
+StayOnTop=0
+
+[ToDo List]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1140
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1140
+TBDockHeight=1151
+LRDockWidth=3675
+Dockable=1
+StayOnTop=0
+Column0Width=314
+Column1Width=30
+Column2Width=150
+Column3Width=172
+Column4Width=129
+SortOrder=4
+ShowHints=1
+ShowChecked=1
+
+[DataExplorerContainer]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=4884
+LRDockWidth=7150
+Dockable=1
+StayOnTop=0
+
+[GraphDrawingModel]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2856
+Height=3209
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2856
+ClientHeight=3209
+TBDockHeight=3209
+LRDockWidth=2856
+Dockable=1
+StayOnTop=0
+
+[ClassBrowserTool]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=-318
+Top=-363
+Width=1850
+Height=3140
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1850
+ClientHeight=3140
+TBDockHeight=3140
+LRDockWidth=1850
+Dockable=1
+StayOnTop=0
+
+[MetricsView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1163
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1163
+TBDockHeight=4837
+LRDockWidth=3562
+Dockable=1
+StayOnTop=0
+
+[QAView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1163
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1163
+TBDockHeight=4837
+LRDockWidth=3562
+Dockable=1
+StayOnTop=0
+
+[BreakpointWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=1547
+LRDockWidth=8744
+Dockable=1
+StayOnTop=0
+Column0Width=200
+Column1Width=75
+Column2Width=200
+Column3Width=200
+Column4Width=200
+Column5Width=75
+Column6Width=75
+
+[StructureView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1894
+Height=3419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1894
+ClientHeight=3419
+TBDockHeight=3674
+LRDockWidth=1894
+Dockable=1
+StayOnTop=0
+
+[fmGrepResults]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=0
+State=0
+Left=0
+Top=0
+Width=2575
+Height=4372
+MaxLeft=-6
+MaxTop=-12
+ClientWidth=2475
+ClientHeight=3919
+TBDockHeight=4372
+LRDockWidth=2575
+Dockable=1
+StayOnTop=0
+
+[ModelViewTool]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=4884
+LRDockWidth=5306
+Dockable=1
+StayOnTop=0
+
+[BorlandEditorCodeExplorer@EditWindow0]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=0
+State=0
+Left=0
+Top=0
+Width=1825
+Height=6174
+MaxLeft=-6
+MaxTop=-12
+ClientWidth=1725
+ClientHeight=5721
+TBDockHeight=6174
+LRDockWidth=1825
+Dockable=1
+StayOnTop=0
+
+[DockHosts]
+DockHostCount=5
+
+[DockSite0]
+HostDockSite=DockBottomCenterPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=8
+Top=8
+Width=2338
+Height=1477
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1477
+TBDockHeight=1477
+LRDockWidth=2338
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=RefactoringForm
+TabDockClients=RefactoringForm,PatchForm,FindReferencsForm,ToDo List,MetricsView,QAView
+
+[DockSite1]
+HostDockSite=DockBottomPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=8
+Top=8
+Width=3825
+Height=1419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1419
+TBDockHeight=1419
+LRDockWidth=3825
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=DebugLogView
+TabDockClients=DebugLogView,BreakpointWindow,ThreadStatusWindow,CallStackWindow,WatchWindow,LocalVarsWindow
+
+[DockSite2]
+HostDockSite=DockRightPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=28
+Width=1525
+Height=4477
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4477
+TBDockHeight=9012
+LRDockWidth=1525
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=ProjectManager
+TabDockClients=ProjectManager,ModelViewTool,DataExplorerContainer,frmDesignPreview
+
+[DockSite3]
+HostDockSite=DockLeftPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=28
+Width=1894
+Height=3419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1894
+ClientHeight=3419
+TBDockHeight=9012
+LRDockWidth=1894
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=StructureView
+TabDockClients=StructureView,ClassBrowserTool
+
+[DockSite4]
+HostDockSite=DockRightPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=449
+Width=1525
+Height=3616
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=3616
+TBDockHeight=9012
+LRDockWidth=1525
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=ToolForm
+TabDockClients=ToolForm,TemplateView
+
diff --git a/Demos/SimpleSockets/Server/Server.identcache b/Demos/SimpleSockets/Server/Server.identcache
new file mode 100644
index 0000000..30a9b20
Binary files /dev/null and b/Demos/SimpleSockets/Server/Server.identcache differ
diff --git a/Demos/SimpleSockets/Server/Server.res b/Demos/SimpleSockets/Server/Server.res
new file mode 100644
index 0000000..0af1ebd
Binary files /dev/null and b/Demos/SimpleSockets/Server/Server.res differ
diff --git a/Demos/SimpleSockets/Srv/Server.skincfg b/Demos/SimpleSockets/Server/Server.skincfg
similarity index 94%
rename from Demos/SimpleSockets/Srv/Server.skincfg
rename to Demos/SimpleSockets/Server/Server.skincfg
index 9e7a05b..0f00ce7 100644
--- a/Demos/SimpleSockets/Srv/Server.skincfg
+++ b/Demos/SimpleSockets/Server/Server.skincfg
@@ -1,33 +1,33 @@
-[ExpressSkins]
-Default=1
-ShowNotifications=1
-Enabled=1
-dxSkinBlack=1
-dxSkinBlue=0
-dxSkinCaramel=0
-dxSkinCoffee=0
-dxSkinDarkRoom=0
-dxSkinDarkSide=1
-dxSkinFoggy=0
-dxSkinGlassOceans=0
-dxSkiniMaginary=0
-dxSkinLilian=0
-dxSkinLiquidSky=0
-dxSkinLondonLiquidSky=0
-dxSkinMcSkin=0
-dxSkinMoneyTwins=0
-dxSkinOffice2007Black=1
-dxSkinOffice2007Blue=0
-dxSkinOffice2007Green=0
-dxSkinOffice2007Pink=0
-dxSkinOffice2007Silver=1
-dxSkinPumpkin=0
-dxSkinSeven=0
-dxSkinSharp=0
-dxSkinSilver=0
-dxSkinSpringTime=0
-dxSkinStardust=0
-dxSkinSummer2008=0
-dxSkinsDefaultPainters=0
-dxSkinValentine=0
-dxSkinXmas2008Blue=0
+[ExpressSkins]
+Default=1
+ShowNotifications=1
+Enabled=1
+dxSkinBlack=1
+dxSkinBlue=0
+dxSkinCaramel=0
+dxSkinCoffee=0
+dxSkinDarkRoom=0
+dxSkinDarkSide=1
+dxSkinFoggy=0
+dxSkinGlassOceans=0
+dxSkiniMaginary=0
+dxSkinLilian=0
+dxSkinLiquidSky=0
+dxSkinLondonLiquidSky=0
+dxSkinMcSkin=0
+dxSkinMoneyTwins=0
+dxSkinOffice2007Black=1
+dxSkinOffice2007Blue=0
+dxSkinOffice2007Green=0
+dxSkinOffice2007Pink=0
+dxSkinOffice2007Silver=1
+dxSkinPumpkin=0
+dxSkinSeven=0
+dxSkinSharp=0
+dxSkinSilver=0
+dxSkinSpringTime=0
+dxSkinStardust=0
+dxSkinSummer2008=0
+dxSkinsDefaultPainters=0
+dxSkinValentine=0
+dxSkinXmas2008Blue=0
diff --git a/Demos/SimpleSockets/Srv/Server_Icon.ico b/Demos/SimpleSockets/Server/Server_Icon.ico
similarity index 100%
rename from Demos/SimpleSockets/Srv/Server_Icon.ico
rename to Demos/SimpleSockets/Server/Server_Icon.ico
diff --git a/Demos/SimpleSockets/Srv/ufrmMain.dfm b/Demos/SimpleSockets/Server/ufrmMain.dfm
similarity index 89%
rename from Demos/SimpleSockets/Srv/ufrmMain.dfm
rename to Demos/SimpleSockets/Server/ufrmMain.dfm
index 0e1ff11..96dd8cd 100644
--- a/Demos/SimpleSockets/Srv/ufrmMain.dfm
+++ b/Demos/SimpleSockets/Server/ufrmMain.dfm
@@ -1,113 +1,110 @@
-object frmMain: TfrmMain
- Left = 0
- Top = 0
- Caption = 'TCPServer'
- ClientHeight = 243
- ClientWidth = 527
- Color = clBtnFace
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- OldCreateOrder = False
- OnCreate = FormCreate
- OnDestroy = FormDestroy
- PixelsPerInch = 96
- TextHeight = 13
- object memLog: TMemo
- AlignWithMargins = True
- Left = 5
- Top = 37
- Width = 517
- Height = 201
- Margins.Left = 5
- Margins.Top = 0
- Margins.Right = 5
- Margins.Bottom = 5
- Align = alClient
- ReadOnly = True
- ScrollBars = ssVertical
- TabOrder = 0
- end
- object pnlToolbar: TPanel
- Left = 0
- Top = 0
- Width = 527
- Height = 37
- Align = alTop
- BevelOuter = bvNone
- FullRepaint = False
- TabOrder = 1
- object btnActivate: TButton
- AlignWithMargins = True
- Left = 5
- Top = 5
- Width = 105
- Height = 27
- Margins.Left = 5
- Margins.Top = 5
- Margins.Right = 5
- Margins.Bottom = 5
- Align = alLeft
- Caption = 'Activate'
- TabOrder = 0
- OnClick = btnActivateClick
- end
- object pblPort: TPanel
- AlignWithMargins = True
- Left = 115
- Top = 3
- Width = 412
- Height = 31
- Margins.Left = 0
- Margins.Right = 0
- Align = alClient
- BevelOuter = bvNone
- FullRepaint = False
- TabOrder = 1
- ExplicitLeft = 110
- ExplicitWidth = 417
- object edtPort: TSpinEdit
- AlignWithMargins = True
- Left = 0
- Top = 5
- Width = 121
- Height = 22
- Margins.Left = 0
- Margins.Top = 5
- Margins.Right = 5
- Margins.Bottom = 5
- Align = alLeft
- MaxValue = 0
- MinValue = 0
- TabOrder = 0
- Value = 16233
- OnChange = edtPortChange
- ExplicitLeft = 291
- end
- object btnShutdownAllClients: TButton
- AlignWithMargins = True
- Left = 256
- Top = 5
- Width = 151
- Height = 21
- Margins.Left = 5
- Margins.Top = 5
- Margins.Right = 5
- Margins.Bottom = 5
- Align = alRight
- Caption = 'Shutdown all clients'
- TabOrder = 1
- OnClick = btnShutdownAllClientsClick
- end
- end
- end
- object TCPServer: TncTCPServer
- OnConnected = TCPServerConnected
- OnDisconnected = TCPServerDisconnected
- OnReadData = TCPServerReadData
- Left = 92
- Top = 52
- end
-end
+object Form1: TForm1
+ Left = 0
+ Top = 0
+ Caption = 'TCPServer'
+ ClientHeight = 243
+ ClientWidth = 527
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ Position = poScreenCenter
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ TextHeight = 13
+ object memLog: TMemo
+ AlignWithMargins = True
+ Left = 5
+ Top = 37
+ Width = 517
+ Height = 201
+ Margins.Left = 5
+ Margins.Top = 0
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alClient
+ ReadOnly = True
+ ScrollBars = ssVertical
+ TabOrder = 0
+ OnKeyDown = memLogKeyDown
+ end
+ object pnlToolbar: TPanel
+ Left = 0
+ Top = 0
+ Width = 527
+ Height = 37
+ Align = alTop
+ BevelOuter = bvNone
+ FullRepaint = False
+ TabOrder = 1
+ object btnActivate: TButton
+ AlignWithMargins = True
+ Left = 5
+ Top = 5
+ Width = 105
+ Height = 27
+ Margins.Left = 5
+ Margins.Top = 5
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alLeft
+ Caption = 'Activate'
+ TabOrder = 0
+ OnClick = btnActivateClick
+ end
+ object pblPort: TPanel
+ AlignWithMargins = True
+ Left = 115
+ Top = 3
+ Width = 412
+ Height = 31
+ Margins.Left = 0
+ Margins.Right = 0
+ Align = alClient
+ BevelOuter = bvNone
+ FullRepaint = False
+ TabOrder = 1
+ object edtPort: TSpinEdit
+ AlignWithMargins = True
+ Left = 0
+ Top = 5
+ Width = 121
+ Height = 22
+ Margins.Left = 0
+ Margins.Top = 5
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alLeft
+ MaxValue = 0
+ MinValue = 0
+ TabOrder = 0
+ Value = 16233
+ OnChange = edtPortChange
+ end
+ object btnShutdownAllClients: TButton
+ AlignWithMargins = True
+ Left = 256
+ Top = 5
+ Width = 151
+ Height = 21
+ Margins.Left = 5
+ Margins.Top = 5
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alRight
+ Caption = 'Shutdown all clients'
+ TabOrder = 1
+ OnClick = btnShutdownAllClientsClick
+ end
+ end
+ end
+ object TCPServer: TncTCPServer
+ OnConnected = TCPServerConnected
+ OnDisconnected = TCPServerDisconnected
+ OnReadData = TCPServerReadData
+ Left = 92
+ Top = 52
+ end
+end
diff --git a/Demos/SimpleSockets/Server/ufrmMain.pas b/Demos/SimpleSockets/Server/ufrmMain.pas
new file mode 100644
index 0000000..6ea2344
--- /dev/null
+++ b/Demos/SimpleSockets/Server/ufrmMain.pas
@@ -0,0 +1,183 @@
+unit ufrmMain;
+
+interface
+
+uses
+{$IFDEF MSWINDOWS}
+ WinApi.Windows, WinApi.Winsock2,
+{$ELSE}
+ Posix.SysSocket, Posix.Unistd,
+{$ENDIF}
+ System.Classes, System.SysUtils, Vcl.Forms, Vcl.Controls, Vcl.StdCtrls,
+ Vcl.ExtCtrls, Vcl.Samples.Spin,
+ System.Diagnostics, ncLines, ncSocketList, ncSockets;
+
+type
+ TForm1 = class(TForm)
+ memLog: TMemo;
+ TCPServer: TncTCPServer;
+ pnlToolbar: TPanel;
+ btnActivate: TButton;
+ pblPort: TPanel;
+ edtPort: TSpinEdit;
+ btnShutdownAllClients: TButton;
+ procedure FormCreate(Sender: TObject);
+ procedure FormDestroy(Sender: TObject);
+ procedure TCPServerConnected(Sender: TObject; aLine: TncLine);
+ procedure TCPServerDisconnected(Sender: TObject; aLine: TncLine);
+ procedure btnActivateClick(Sender: TObject);
+ procedure edtPortChange(Sender: TObject);
+ procedure btnShutdownAllClientsClick(Sender: TObject);
+ procedure TCPServerReadData(Sender: TObject; aLine: TncLine;
+ const aBuf: TBytes; aBufCount: Integer);
+ procedure Log(const AMessage: string);
+ procedure memLogKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
+ private
+ public
+ end;
+
+var
+ Form1: TForm1;
+
+implementation
+
+{$R *.dfm}
+
+procedure TForm1.FormCreate(Sender: TObject);
+begin
+//
+end;
+
+procedure TForm1.FormDestroy(Sender: TObject);
+begin
+ TCPServer.Active := False;
+end;
+
+// *****************************************************************************
+// Start/Stop Main Server
+// *****************************************************************************
+procedure TForm1.btnActivateClick(Sender: TObject);
+begin
+ if TCPServer.Active then
+ begin
+ // Deactivate the TCP Server
+ TCPServer.Active := False;
+ btnActivate.Caption := 'Start TCP Server';
+ Log('TCP Server Deactivated');
+ end
+ else
+ begin
+ try
+ // Activate the TCP Server
+ TCPServer.Active := True;
+ btnActivate.Caption := 'Stop TCP Server';
+ Log('TCP Server Activated at port: ' + IntToStr(TCPServer.Port));
+
+ except
+ on E: Exception do
+ Log('Failed to activate TCP Server: ' + E.Message);
+ end;
+ end;
+end;
+
+// *****************************************************************************
+// Change Main Client port
+// *****************************************************************************
+procedure TForm1.edtPortChange(Sender: TObject);
+begin
+ try
+ TCPServer.Port := edtPort.Value;
+ except
+ edtPort.OnChange := nil;
+ try
+ edtPort.Value := TCPServer.Port;
+ finally
+ edtPort.OnChange := edtPortChange;
+ end;
+ raise;
+ end;
+end;
+
+// *****************************************************************************
+// Shutdown all Clients
+// *****************************************************************************
+procedure TForm1.btnShutdownAllClientsClick(Sender: TObject);
+var
+ SocketList: TSocketList;
+ i: Integer;
+begin
+ SocketList := TCPServer.Lines.LockList;
+ try
+ for i := 0 to SocketList.Count - 1 do
+ TCPServer.ShutDownLine(SocketList.Lines[i]);
+ finally
+ TCPServer.Lines.UnlockList;
+ end;
+end;
+
+// *****************************************************************************
+// TCPServerConnected
+// *****************************************************************************
+procedure TForm1.TCPServerConnected(Sender: TObject; aLine: TncLine);
+begin
+
+ Log('Connected: ' + aLine.PeerIP);
+
+ TCPServer.Send(aLine, BytesOf('Hello mr. ' + IntToStr(aLine.Handle)));
+end;
+
+// *****************************************************************************
+// TCPServerDisconnected
+// *****************************************************************************
+procedure TForm1.TCPServerDisconnected(Sender: TObject; aLine: TncLine);
+begin
+
+ Log('Disconnected: ' + aLine.PeerIP);
+
+end;
+
+// *****************************************************************************
+// Read Data
+// *****************************************************************************
+procedure TForm1.TCPServerReadData(Sender: TObject; aLine: TncLine;
+ const aBuf: TBytes; aBufCount: Integer);
+var
+ BytesReceived: TBytes;
+begin
+ BytesReceived := Copy(aBuf, 0, aBufCount);
+
+ Log('Received: "' + StringOf(BytesReceived) + '" from: ' + aLine.PeerIP);
+
+ // Send back the buffer received
+ TCPServer.Send(aLine, BytesReceived);
+
+ Log('Data sent: ' + StringOf(BytesReceived));
+
+end;
+
+// *****************************************************************************
+// Memo Log
+// *****************************************************************************
+procedure TForm1.Log(const AMessage: string);
+begin
+ TThread.Queue(nil,
+ procedure
+ begin
+ try
+ memLog.Lines.Add(Format('[%s] %s', [FormatDateTime('hh:nn:ss.zzz', Now),
+ AMessage]));
+ finally
+ end;
+ end);
+end;
+
+procedure TForm1.memLogKeyDown(Sender: TObject; var Key: Word;
+Shift: TShiftState);
+begin
+ if (Shift = [ssCtrl]) and (Key = Ord('A')) then
+ memLog.SelectAll
+ else if (Shift = [ssCtrl]) and (Key = Ord('C')) then
+ memLog.CopyToClipboard;
+end;
+
+end.
diff --git a/Demos/SimpleSockets/SimpleSockets.groupproj b/Demos/SimpleSockets/SimpleSockets.groupproj
new file mode 100644
index 0000000..9547a87
--- /dev/null
+++ b/Demos/SimpleSockets/SimpleSockets.groupproj
@@ -0,0 +1,48 @@
+
+
+ {D340A737-6F7F-41B2-ABE1-FF55CC85A4DB}
+
+
+
+
+
+
+
+
+
+
+ Default.Personality.12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Demos/SimpleSockets/SimpleSockets_TCPv4.PNG b/Demos/SimpleSockets/SimpleSockets_TCPv4.PNG
new file mode 100644
index 0000000..95f8d5d
Binary files /dev/null and b/Demos/SimpleSockets/SimpleSockets_TCPv4.PNG differ
diff --git a/Demos/SimpleSockets/SimpleSockets_TCPv6.PNG b/Demos/SimpleSockets/SimpleSockets_TCPv6.PNG
new file mode 100644
index 0000000..9549054
Binary files /dev/null and b/Demos/SimpleSockets/SimpleSockets_TCPv6.PNG differ
diff --git a/Demos/SimpleSockets/Srv/Server.identcache b/Demos/SimpleSockets/Srv/Server.identcache
deleted file mode 100644
index 764389c..0000000
Binary files a/Demos/SimpleSockets/Srv/Server.identcache and /dev/null differ
diff --git a/Demos/SimpleSockets/Srv/Server.res b/Demos/SimpleSockets/Srv/Server.res
deleted file mode 100644
index 8002f6e..0000000
Binary files a/Demos/SimpleSockets/Srv/Server.res and /dev/null differ
diff --git a/Demos/SimpleSockets/Srv/ufrmMain.pas b/Demos/SimpleSockets/Srv/ufrmMain.pas
deleted file mode 100644
index f2ff91e..0000000
--- a/Demos/SimpleSockets/Srv/ufrmMain.pas
+++ /dev/null
@@ -1,140 +0,0 @@
-unit ufrmMain;
-
-interface
-
-uses
-{$IFDEF MSWINDOWS}
- WinApi.Windows, WinApi.Winsock2,
-{$ELSE}
- Posix.SysSocket, Posix.Unistd,
-{$ENDIF}
- System.Classes, System.SysUtils, Vcl.Forms, Vcl.Controls, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Samples.Spin,
- System.Diagnostics, ncLines, ncSocketList, ncSockets;
-
-type
- TfrmMain = class(TForm)
- memLog: TMemo;
- TCPServer: TncTCPServer;
- pnlToolbar: TPanel;
- btnActivate: TButton;
- pblPort: TPanel;
- edtPort: TSpinEdit;
- btnShutdownAllClients: TButton;
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure TCPServerConnected(Sender: TObject; aLine: TncLine);
- procedure TCPServerDisconnected(Sender: TObject; aLine: TncLine);
- procedure TCPServerReadData(Sender: TObject; aLine: TncLine; const aBuf: TArray; aBufCount: Integer);
- procedure btnActivateClick(Sender: TObject);
- procedure edtPortChange(Sender: TObject);
- procedure btnShutdownAllClientsClick(Sender: TObject);
- private
- public
- end;
-
-var
- frmMain: TfrmMain;
-
-implementation
-
-{$R *.dfm}
-
-procedure TfrmMain.FormCreate(Sender: TObject);
-begin
- try
- TCPServer.Active := True;
- memLog.Lines.Add('Server is active at port: ' + IntToStr(TCPServer.Port));
- btnActivate.Caption := 'Deactivate';
- except
- on e: Exception do
- memLog.Lines.Add('Server cannot activate. ' + e.Message);
- end;
-end;
-
-procedure TfrmMain.FormDestroy(Sender: TObject);
-begin
- TCPServer.Active := False;
-end;
-
-procedure TfrmMain.btnActivateClick(Sender: TObject);
-begin
- try
- TCPServer.Active := not TCPServer.Active;
- finally
- if TCPServer.Active then
- begin
- memLog.Lines.Add('Server is active at port: ' + IntToStr(TCPServer.Port));
- btnActivate.Caption := 'Deactivate';
- end
- else
- begin
- memLog.Lines.Add('Server was deactivated');
- btnActivate.Caption := 'Activate';
- end;
- end;
-end;
-
-procedure TfrmMain.edtPortChange(Sender: TObject);
-begin
- try
- TCPServer.Port := edtPort.Value;
- except
- // if it is active, it will not allow us to change the value,
- // revert the edtPort value to its original
- edtPort.Value := TCPServer.Port;
- raise; // Reraise the exception so as the user sees the error
- end;
-end;
-
-procedure TfrmMain.btnShutdownAllClientsClick(Sender: TObject);
-var
- SocketList: TSocketList;
- i: Integer;
-begin
- SocketList := TCPServer.Lines.LockList;
- try
- for i := 0 to SocketList.Count - 1 do
- TCPServer.ShutDownLine(SocketList.Lines[i]);
- finally
- TCPServer.Lines.UnlockList;
- end;
-end;
-
-
-procedure TfrmMain.TCPServerConnected(Sender: TObject; aLine: TncLine);
-begin
- TThread.Synchronize(nil,
- procedure
- begin
- memLog.Lines.Add('Connected: ' + aLine.PeerIP);
- end);
-
- TCPServer.Send(aLine, BytesOf('Hello mr. ' + IntToStr(aLine.Handle)));
-end;
-
-procedure TfrmMain.TCPServerDisconnected(Sender: TObject; aLine: TncLine);
-begin
- TThread.Synchronize(nil,
- procedure
- begin
- memLog.Lines.Add('Disconnected: ' + aLine.PeerIP);
- end);
-end;
-
-procedure TfrmMain.TCPServerReadData(Sender: TObject; aLine: TncLine; const aBuf: TArray; aBufCount: Integer);
-var
- BytesReceived: TBytes;
-begin
- BytesReceived := Copy(aBuf, 0, aBufCount);
-
- TThread.Queue(nil,
- procedure
- begin
- memLog.Lines.Add('Received: "' + StringOf(BytesReceived) + '" from: ' + aLine.PeerIP);
- end);
-
- // Send back the buffer received
- TCPServer.Send(aLine, BytesReceived);
-end;
-
-end.
diff --git a/Demos/SimpleSockets/ufrmMain.pas b/Demos/SimpleSockets/ufrmMain.pas
deleted file mode 100644
index 2c10902..0000000
--- a/Demos/SimpleSockets/ufrmMain.pas
+++ /dev/null
@@ -1,147 +0,0 @@
-unit ufrmMain;
-
-interface
-
-uses
-{$IFDEF MSWINDOWS}
- WinApi.Windows, WinApi.Winsock2,
-{$ELSE}
- Posix.SysSocket, Posix.Unistd,
-{$ENDIF}
- System.Classes, System.SysUtils, Vcl.Forms, Vcl.Controls, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Samples.Spin,
- System.Diagnostics, ncLines, ncSockets;
-
-type
- TForm1 = class(TForm)
- memLog: TMemo;
- TCPClient: TncTCPClient;
- pnlToolbar: TPanel;
- btnActivate: TButton;
- pnlAddress: TPanel;
- edtHost: TEdit;
- edtPort: TSpinEdit;
- Panel1: TPanel;
- btnSendData: TButton;
- Panel2: TPanel;
- edtDataToSend: TEdit;
- procedure btnActivateClick(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure TCPClientConnected(Sender: TObject; aLine: TncLine);
- procedure TCPClientDisconnected(Sender: TObject; aLine: TncLine);
- procedure TCPClientReconnected(Sender: TObject; aLine: TncLine);
- procedure TCPClientReadData(Sender: TObject; aLine: TncLine; const aBuf: TArray; aBufCount: Integer);
- procedure edtHostChange(Sender: TObject);
- procedure edtPortChange(Sender: TObject);
- procedure btnSendDataClick(Sender: TObject);
- procedure edtDataToSendEnter(Sender: TObject);
- procedure edtDataToSendExit(Sender: TObject);
- private
- public
- end;
-
-var
- Form1: TForm1;
-
-implementation
-
-{$R *.dfm}
-
-procedure TForm1.FormDestroy(Sender: TObject);
-begin
- TCPClient.Active := False;
-end;
-
-procedure TForm1.edtHostChange(Sender: TObject);
-begin
- try
- TCPClient.Host := edtHost.Text;
- except
- edtHost.OnChange := nil;
- try
- edtHost.Text := TCPClient.Host;
- finally
- edtHost.OnChange := edtHostChange;
- end;
- raise;
- end;
-end;
-
-procedure TForm1.edtPortChange(Sender: TObject);
-begin
- try
- TCPClient.Port := edtPort.Value;
- except
- edtPort.OnChange := nil;
- try
- edtPort.Value := TCPClient.Port;
- finally
- edtPort.OnChange := edtPortChange;
- end;
- raise;
- end;
-end;
-
-procedure TForm1.btnActivateClick(Sender: TObject);
-begin
- TCPClient.Active := not TCPClient.Active;
-end;
-
-procedure TForm1.edtDataToSendEnter(Sender: TObject);
-begin
- btnSendData.Default := True;
-end;
-
-procedure TForm1.edtDataToSendExit(Sender: TObject);
-begin
- btnSendData.Default := False;
-end;
-
-procedure TForm1.TCPClientConnected(Sender: TObject; aLine: TncLine);
-begin
- TThread.Synchronize(nil,
- procedure
- begin
- memLog.Lines.Add('Connected');
- btnActivate.Caption := 'Deactivate';
- end);
-end;
-
-procedure TForm1.TCPClientDisconnected(Sender: TObject; aLine: TncLine);
-begin
- TThread.Synchronize(nil,
- procedure
- begin
- memLog.Lines.Add('Disconnected');
- btnActivate.Caption := 'Activate';
- end);
-end;
-
-procedure TForm1.TCPClientReconnected(Sender: TObject; aLine: TncLine);
-begin
- TThread.Synchronize(nil,
- procedure
- begin
- memLog.Lines.Add('Reconnected');
- end);
-end;
-
-procedure TForm1.TCPClientReadData(Sender: TObject; aLine: TncLine; const aBuf: TArray; aBufCount: Integer);
-var
- BytesReceived: TBytes;
-begin
- BytesReceived := Copy(aBuf, 0, aBufCount);
-
- TThread.Synchronize(nil,
- procedure
- begin
- memLog.Lines.Add('Received: ' + StringOf(BytesReceived));
- end);
-end;
-
-procedure TForm1.btnSendDataClick(Sender: TObject);
-begin
- TCPClient.Send(edtDataToSend.Text);
-end;
-
-
-end.
diff --git a/Demos/SimpleSockets_UDP/Client/Client.dpr b/Demos/SimpleSockets_UDP/Client/Client.dpr
new file mode 100644
index 0000000..aa89c08
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Client/Client.dpr
@@ -0,0 +1,17 @@
+program Client;
+
+uses
+ Vcl.Forms,
+ ufrmMain in 'ufrmMain.pas' {Form1};
+
+{$R *.res}
+
+begin
+ {$IFDEF DEBUG}
+ ReportMemoryLeaksOnShutdown := True;
+ {$ENDIF}
+ Application.Initialize;
+ Application.MainFormOnTaskbar := True;
+ Application.CreateForm(TForm1, Form1);
+ Application.Run;
+end.
diff --git a/Demos/SimpleSockets_UDP/Client/Client.dproj b/Demos/SimpleSockets_UDP/Client/Client.dproj
new file mode 100644
index 0000000..2a5f98a
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Client/Client.dproj
@@ -0,0 +1,1165 @@
+
+
+ {2F2F33BE-2A99-4B2A-A206-E1E4DE8915A3}
+ 20.2
+ Client.dpr
+ Release
+ DCC32
+ VCL
+ True
+ Win64
+ 3
+ Application
+ Client
+
+
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ Client.exe
+ off
+ vclx;vcl;vclimg;dbrtl;Rave77VCL;bdertl;rtl;vclactnband;xmlrtl;vcldb;vcldbx;vcltouch;dsnap;dsnapcon;TeeUI;TeeDB;Tee;vclib;ibxpress;adortl;IndyCore;IndySystem;IndyProtocols;inet;intrawebdb_100_140;Intraweb_100_140;VclSmp;vclie;websnap;webdsnap;inetdb;inetdbbde;inetdbxpress;soaprtl;vclribbon;dbexpress;DbxCommonDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;DbxClientDriver;DataSnapServer;DBXInterBaseDriver;DBXMySQLDriver;dbxcds;DBXFirebirdDriver;DBXSybaseASEDriver;DBXSybaseASADriver;DBXOracleDriver;DBXMSSQLDriver;DBXInformixDriver;DBXDb2Driver;dclOfficeXP;$(DCC_UsePackage)
+ $(BDSCOMMONDIR)\DCP
+ $(BDSCOMMONDIR)\DCU
+ x86
+ 00400000
+ Client
+ Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)
+ true
+ 1032
+ CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
+
+
+ android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
+
+
+ System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
+ Debug
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
+ 1033
+ $(BDS)\bin\default_app.manifest
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ true
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+
+
+ $(BDS)\bin\default_app.manifest
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ true
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+ System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
+ Debug
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+ 1033
+
+
+ false
+ RELEASE;$(DCC_Define)
+ 0
+ 0
+
+
+ true
+ PerMonitorV2
+
+
+ true
+ PerMonitorV2
+
+
+ DEBUG;$(DCC_Define)
+
+
+ Debug
+
+
+ true
+ PerMonitorV2
+
+
+ true
+ PerMonitorV2
+ 1033
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+
+
+
+ MainSource
+
+
+
+
+
+ Base
+
+
+ Cfg_1
+ Base
+
+
+ Cfg_2
+ Base
+
+
+
+
+ Delphi.Personality.12
+
+
+
+
+ Client.dpr
+
+
+ False
+ True
+ False
+
+
+ True
+ False
+ 1
+ 0
+ 0
+ 0
+ False
+ False
+ False
+ False
+ False
+ 1032
+ 1253
+
+
+
+
+ 1.0.0.0
+
+
+
+
+
+ 1.0.0.0
+
+
+
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+
+
+
+ False
+ True
+ True
+
+
+
+
+ Client.exe
+ true
+
+
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ 0
+
+
+
+
+ res\xml
+ 1
+
+
+ res\xml
+ 1
+
+
+
+
+ library\lib\armeabi
+ 1
+
+
+ library\lib\armeabi
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ library\lib\mips
+ 1
+
+
+ library\lib\mips
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-anydpi-v21
+ 1
+
+
+ res\drawable-anydpi-v21
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\values-v21
+ 1
+
+
+ res\values-v21
+ 1
+
+
+
+
+ res\values-v31
+ 1
+
+
+ res\values-v31
+ 1
+
+
+
+
+ res\drawable-anydpi-v26
+ 1
+
+
+ res\drawable-anydpi-v26
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-anydpi-v33
+ 1
+
+
+ res\drawable-anydpi-v33
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\values-night-v21
+ 1
+
+
+ res\values-night-v21
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+
+
+ res\drawable-ldpi
+ 1
+
+
+ res\drawable-ldpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+
+
+ res\drawable-small
+ 1
+
+
+ res\drawable-small
+ 1
+
+
+
+
+ res\drawable-normal
+ 1
+
+
+ res\drawable-normal
+ 1
+
+
+
+
+ res\drawable-large
+ 1
+
+
+ res\drawable-large
+ 1
+
+
+
+
+ res\drawable-xlarge
+ 1
+
+
+ res\drawable-xlarge
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\drawable-anydpi-v24
+ 1
+
+
+ res\drawable-anydpi-v24
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-night-anydpi-v21
+ 1
+
+
+ res\drawable-night-anydpi-v21
+ 1
+
+
+
+
+ res\drawable-anydpi-v31
+ 1
+
+
+ res\drawable-anydpi-v31
+ 1
+
+
+
+
+ res\drawable-night-anydpi-v31
+ 1
+
+
+ res\drawable-night-anydpi-v31
+ 1
+
+
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ 0
+
+
+
+
+ Contents\MacOS
+ 1
+ .framework
+
+
+ Contents\MacOS
+ 1
+ .framework
+
+
+ Contents\MacOS
+ 1
+ .framework
+
+
+ 0
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ 0
+ .dll;.bpl
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ 0
+ .bpl
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ Contents\Resources\StartUp\
+ 0
+
+
+ Contents\Resources\StartUp\
+ 0
+
+
+ Contents\Resources\StartUp\
+ 0
+
+
+ 0
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+
+
+ Contents
+ 1
+
+
+ Contents
+ 1
+
+
+ Contents
+ 1
+
+
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ 0
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen
+ 64
+
+
+ ..\$(PROJECTNAME).launchscreen
+ 64
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 12
+
+
+
+
diff --git a/Demos/SimpleSockets_UDP/Client/Client.dproj.local b/Demos/SimpleSockets_UDP/Client/Client.dproj.local
new file mode 100644
index 0000000..8b0113d
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Client/Client.dproj.local
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+ 2025/01/14 21:49:41.000.186,=D:\_Delphi\_Library\Netcom7\Demos\SimpleSockets_UDP\Client\Unit1.pas
+ 2025/01/14 21:49:56.000.966,D:\_Delphi\_Library\Netcom7\Demos\SimpleSockets_UDP\Client\uMainClient.pas=D:\_Delphi\_Library\Netcom7\Demos\SimpleSockets_UDP\Client\Unit1.pas
+ 2025/01/16 20:06:27.000.079,D:\_Delphi\_Library\NetCom7\Demos\SimpleSockets_UDP_v2\Client\uMainClient.pas=
+
+
diff --git a/Demos/SimpleSockets_UDP/Client/Client.dsk b/Demos/SimpleSockets_UDP/Client/Client.dsk
new file mode 100644
index 0000000..38e48cb
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Client/Client.dsk
@@ -0,0 +1,769 @@
+[Closed Files]
+File_0=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\SOURCE\VCL\Vcl.Forms.pas',0,1,1,6,10,0,0,{{1755,4}
+File_1=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas',0,1,9,1,59,0,0,,
+File_2=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpDXAPIHelpers.pas',0,1,1,1,5,0,0,,{1
+File_3=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncThreads.pas',0,1,88,13,95,0,0,,
+File_4=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpDXAPI.pas',0,1,1,1,1,0,0,,{1
+File_5=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectX9\uD3DX9.pas',0,1,5404,1,5435,0,0,,
+File_6=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectX9\uDirect3D9.pas',0,1,3093,1,3112,0,0,,
+File_7=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpTypes.pas',0,1,404,1,417,0,0,,
+File_8=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpDirectPanel.pas',0,1,2514,5,2533,0,0,,{1
+File_9=TSourceModule,'c:\program files (x86)\embarcadero\rad studio\7.0\SOURCE\WIN32\VCL\Forms.pas',0,1,9739,51,9749,0,0,,
+
+[Modules]
+Module0=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\ufrmMain.pas
+Module1=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Client.dproj
+Count=2
+EditWindowCount=1
+
+[C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\ufrmMain.pas]
+ModuleType=TSourceModule
+
+[C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Client.dproj]
+ModuleType=TBaseProject
+
+[EditWindow0]
+ViewCount=2
+CurrentEditView=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\ufrmMain.pas
+View0=0
+View1=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=9900
+Height=8837
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=9900
+ClientHeight=8837
+DockedToMainForm=1
+BorlandEditorCodeExplorer=BorlandEditorCodeExplorer@EditWindow0
+TopPanelSize=0
+LeftPanelSize=1894
+LeftPanelClients=PropertyInspector,DockSite3
+LeftPanelData=000008000101000000008E120000000000000166070000000000000100000000530E000009000000446F636B53697465330100000000FC2000001100000050726F7065727479496E73706563746F72FFFFFFFF
+RightPanelSize=1525
+RightPanelClients=DockSite2,DockSite4
+RightPanelData=000008000101000000008E1200000000000001F50500000000000001000000004612000009000000446F636B53697465320100000000FC20000009000000446F636B5369746534FFFFFFFF
+BottomPanelSize=0
+BottomPanelClients=DockSite1,MessageView
+BottomPanelData=0000080001020200000009000000446F636B53697465310F0000004D65737361676556696577466F726D1534000000000000022A06000000000000FFFFFFFF
+BottomMiddlePanelSize=0
+BottomMiddlePanelClients=DockSite0,GraphDrawingModel
+BottomMiddelPanelData=0000080001020200000009000000446F636B536974653010000000477261706844726177696E67566965779A1D00000000000002F206000000000000FFFFFFFF
+
+[View0]
+CustomEditViewType=TEditView
+Module=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Client.dpr
+CursorX=11
+CursorY=12
+TopLine=1
+LeftCol=1
+Elisions=
+Bookmarks=
+EditViewName=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Client.dpr
+
+[View1]
+CustomEditViewType=TEditView
+Module=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\ufrmMain.pas
+CursorX=35
+CursorY=130
+TopLine=118
+LeftCol=1
+Elisions=
+Bookmarks=
+EditViewName=Borland.FormDesignerView
+
+[UndockedDesigner]
+Count=0
+
+[Watches]
+Count=0
+
+[WatchWindow]
+WatchColumnWidth=120
+WatchShowColumnHeaders=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=209
+LRDockWidth=13600
+Dockable=1
+StayOnTop=0
+
+[Breakpoints]
+Count=1
+Breakpoint0='C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncSources.pas',973,'',0,1,'',1,0,0,'',1,'','','',0,''
+
+[EmbarcaderoWin32Debugger_AddressBreakpoints]
+Count=0
+
+[EmbarcaderoWin64Debugger_AddressBreakpoints]
+Count=0
+
+[EmbarcaderoAndroid32Debugger_AddressBreakpoints]
+Count=0
+
+[EmbarcaderoAndroid64Debugger_AddressBreakpoints]
+Count=0
+
+[Main Window]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=0
+State=2
+Left=144
+Top=279
+Width=8931
+Height=8523
+MaxLeft=-6
+MaxTop=-12
+MaxWidth=8931
+MaxHeight=8523
+ClientWidth=10025
+ClientHeight=9744
+BottomPanelSize=8444
+BottomPanelClients=EditWindow0
+BottomPanelData=0000080000000000000000000000000000000000000000000000000100000000000000000C0000004564697457696E646F775F30FFFFFFFF
+
+[ProjectManager]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=5895
+LRDockWidth=2350
+Dockable=1
+StayOnTop=0
+
+[MessageView]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2769
+Height=1419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2769
+ClientHeight=1419
+TBDockHeight=1419
+LRDockWidth=2769
+Dockable=1
+StayOnTop=0
+
+[ToolForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=3616
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=3616
+TBDockHeight=7151
+LRDockWidth=2000
+Dockable=1
+StayOnTop=0
+
+[ClipboardHistory]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=0
+State=0
+Left=0
+Top=0
+Width=2338
+Height=5174
+MaxLeft=-6
+MaxTop=-12
+ClientWidth=2262
+ClientHeight=4733
+TBDockHeight=5174
+LRDockWidth=2338
+Dockable=1
+StayOnTop=0
+
+[PropertyInspector]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=358
+Width=1894
+Height=4674
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1894
+ClientHeight=4674
+TBDockHeight=9012
+LRDockWidth=1894
+Dockable=1
+StayOnTop=0
+SplitPos=111
+
+[PropInspDesignerSelection]
+ArrangeBy=Name
+SelectedItem=Action,
+ExpandedItems=LiveBindings=0,"LiveBindings Designer=0",Margins=0,ActiveControl=0,Anchors=0,BorderIcons=0
+
+[frmDesignPreview]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=5953
+LRDockWidth=2512
+Dockable=1
+StayOnTop=0
+
+[TemplateView]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=0
+Top=0
+Width=275
+Height=360
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=275
+ClientHeight=360
+TBDockHeight=360
+LRDockWidth=275
+Dockable=1
+StayOnTop=0
+Name=120
+Description=334
+filter=1
+
+[DebugLogView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=407
+LRDockWidth=4950
+Dockable=1
+StayOnTop=0
+
+[ThreadStatusWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=209
+LRDockWidth=7406
+Dockable=1
+StayOnTop=0
+Column0Width=145
+Column1Width=100
+Column2Width=115
+Column3Width=252
+
+[LocalVarsWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=1535
+LRDockWidth=3481
+Dockable=1
+StayOnTop=0
+
+[CallStackWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=2070
+LRDockWidth=3481
+Dockable=1
+StayOnTop=0
+
+[PatchForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1151
+TBDockHeight=2500
+LRDockWidth=3400
+Dockable=1
+StayOnTop=0
+
+[FindReferencsForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1151
+TBDockHeight=2314
+LRDockWidth=2825
+Dockable=1
+StayOnTop=0
+
+[RefactoringForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1151
+TBDockHeight=3209
+LRDockWidth=2825
+Dockable=1
+StayOnTop=0
+
+[ToDo List]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1140
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1140
+TBDockHeight=1151
+LRDockWidth=3675
+Dockable=1
+StayOnTop=0
+Column0Width=314
+Column1Width=30
+Column2Width=150
+Column3Width=172
+Column4Width=129
+SortOrder=4
+ShowHints=1
+ShowChecked=1
+
+[DataExplorerContainer]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=4884
+LRDockWidth=7150
+Dockable=1
+StayOnTop=0
+
+[GraphDrawingModel]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2856
+Height=3209
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2856
+ClientHeight=3209
+TBDockHeight=3209
+LRDockWidth=2856
+Dockable=1
+StayOnTop=0
+
+[ClassBrowserTool]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=-318
+Top=-363
+Width=1850
+Height=3140
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1850
+ClientHeight=3140
+TBDockHeight=3140
+LRDockWidth=1850
+Dockable=1
+StayOnTop=0
+
+[MetricsView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1163
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1163
+TBDockHeight=4837
+LRDockWidth=3562
+Dockable=1
+StayOnTop=0
+
+[QAView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1163
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1163
+TBDockHeight=4837
+LRDockWidth=3562
+Dockable=1
+StayOnTop=0
+
+[BreakpointWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=1547
+LRDockWidth=8744
+Dockable=1
+StayOnTop=0
+Column0Width=200
+Column1Width=75
+Column2Width=200
+Column3Width=200
+Column4Width=200
+Column5Width=75
+Column6Width=75
+
+[StructureView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1894
+Height=3419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1894
+ClientHeight=3419
+TBDockHeight=3674
+LRDockWidth=1894
+Dockable=1
+StayOnTop=0
+
+[fmGrepResults]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=0
+State=0
+Left=0
+Top=0
+Width=2575
+Height=4372
+MaxLeft=-6
+MaxTop=-12
+ClientWidth=2475
+ClientHeight=3919
+TBDockHeight=4372
+LRDockWidth=2575
+Dockable=1
+StayOnTop=0
+
+[ModelViewTool]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=4884
+LRDockWidth=5306
+Dockable=1
+StayOnTop=0
+
+[BorlandEditorCodeExplorer@EditWindow0]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=0
+State=0
+Left=0
+Top=0
+Width=1825
+Height=6174
+MaxLeft=-6
+MaxTop=-12
+ClientWidth=1725
+ClientHeight=5721
+TBDockHeight=6174
+LRDockWidth=1825
+Dockable=1
+StayOnTop=0
+
+[DockHosts]
+DockHostCount=5
+
+[DockSite0]
+HostDockSite=DockBottomCenterPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=8
+Top=8
+Width=2338
+Height=1477
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1477
+TBDockHeight=1477
+LRDockWidth=2338
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=RefactoringForm
+TabDockClients=RefactoringForm,PatchForm,FindReferencsForm,ToDo List,MetricsView,QAView
+
+[DockSite1]
+HostDockSite=DockBottomPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=8
+Top=8
+Width=3825
+Height=1419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1419
+TBDockHeight=1419
+LRDockWidth=3825
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=DebugLogView
+TabDockClients=DebugLogView,BreakpointWindow,ThreadStatusWindow,CallStackWindow,WatchWindow,LocalVarsWindow
+
+[DockSite2]
+HostDockSite=DockRightPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=28
+Width=1525
+Height=4477
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4477
+TBDockHeight=9012
+LRDockWidth=1525
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=ProjectManager
+TabDockClients=ProjectManager,ModelViewTool,DataExplorerContainer,frmDesignPreview
+
+[DockSite3]
+HostDockSite=DockLeftPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=28
+Width=1894
+Height=3419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1894
+ClientHeight=3419
+TBDockHeight=9012
+LRDockWidth=1894
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=StructureView
+TabDockClients=StructureView,ClassBrowserTool
+
+[DockSite4]
+HostDockSite=DockRightPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=449
+Width=1525
+Height=3616
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=3616
+TBDockHeight=9012
+LRDockWidth=1525
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=ToolForm
+TabDockClients=ToolForm,TemplateView
+
diff --git a/Demos/SimpleSockets_UDP/Client/Client.identcache b/Demos/SimpleSockets_UDP/Client/Client.identcache
new file mode 100644
index 0000000..d4f15fa
Binary files /dev/null and b/Demos/SimpleSockets_UDP/Client/Client.identcache differ
diff --git a/Demos/SimpleSockets_UDP/Client/Client.res b/Demos/SimpleSockets_UDP/Client/Client.res
new file mode 100644
index 0000000..d4b6e46
Binary files /dev/null and b/Demos/SimpleSockets_UDP/Client/Client.res differ
diff --git a/Demos/SimpleSockets_UDP/Client/Client.skincfg b/Demos/SimpleSockets_UDP/Client/Client.skincfg
new file mode 100644
index 0000000..0f00ce7
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Client/Client.skincfg
@@ -0,0 +1,33 @@
+[ExpressSkins]
+Default=1
+ShowNotifications=1
+Enabled=1
+dxSkinBlack=1
+dxSkinBlue=0
+dxSkinCaramel=0
+dxSkinCoffee=0
+dxSkinDarkRoom=0
+dxSkinDarkSide=1
+dxSkinFoggy=0
+dxSkinGlassOceans=0
+dxSkiniMaginary=0
+dxSkinLilian=0
+dxSkinLiquidSky=0
+dxSkinLondonLiquidSky=0
+dxSkinMcSkin=0
+dxSkinMoneyTwins=0
+dxSkinOffice2007Black=1
+dxSkinOffice2007Blue=0
+dxSkinOffice2007Green=0
+dxSkinOffice2007Pink=0
+dxSkinOffice2007Silver=1
+dxSkinPumpkin=0
+dxSkinSeven=0
+dxSkinSharp=0
+dxSkinSilver=0
+dxSkinSpringTime=0
+dxSkinStardust=0
+dxSkinSummer2008=0
+dxSkinsDefaultPainters=0
+dxSkinValentine=0
+dxSkinXmas2008Blue=0
diff --git a/Demos/SimpleSockets_UDP/Client/Client_Icon.ico b/Demos/SimpleSockets_UDP/Client/Client_Icon.ico
new file mode 100644
index 0000000..379ec80
Binary files /dev/null and b/Demos/SimpleSockets_UDP/Client/Client_Icon.ico differ
diff --git a/Demos/SimpleSockets_UDP/Client/ufrmMain.dfm b/Demos/SimpleSockets_UDP/Client/ufrmMain.dfm
new file mode 100644
index 0000000..276505f
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Client/ufrmMain.dfm
@@ -0,0 +1,180 @@
+object Form1: TForm1
+ Left = 0
+ Top = 0
+ ActiveControl = edtDataToSend
+ Caption = 'UDPClient'
+ ClientHeight = 243
+ ClientWidth = 527
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ Position = poScreenCenter
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ TextHeight = 13
+ object memLog: TMemo
+ AlignWithMargins = True
+ Left = 5
+ Top = 37
+ Width = 517
+ Height = 169
+ Margins.Left = 5
+ Margins.Top = 0
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alClient
+ ReadOnly = True
+ ScrollBars = ssVertical
+ TabOrder = 1
+ OnKeyDown = memLogKeyDown
+ ExplicitWidth = 515
+ ExplicitHeight = 161
+ end
+ object pnlToolbar: TPanel
+ Left = 0
+ Top = 0
+ Width = 527
+ Height = 37
+ Align = alTop
+ BevelOuter = bvNone
+ FullRepaint = False
+ TabOrder = 0
+ ExplicitWidth = 525
+ object btnActivate: TButton
+ AlignWithMargins = True
+ Left = 5
+ Top = 5
+ Width = 105
+ Height = 27
+ Margins.Left = 5
+ Margins.Top = 5
+ Margins.Right = 0
+ Margins.Bottom = 5
+ Align = alLeft
+ Caption = 'Start UDP Client'
+ TabOrder = 0
+ OnClick = btnActivateClick
+ end
+ object pnlAddress: TPanel
+ AlignWithMargins = True
+ Left = 110
+ Top = 3
+ Width = 417
+ Height = 31
+ Margins.Left = 0
+ Margins.Right = 0
+ Align = alClient
+ BevelOuter = bvNone
+ FullRepaint = False
+ TabOrder = 1
+ ExplicitWidth = 415
+ object edtHost: TEdit
+ AlignWithMargins = True
+ Left = 5
+ Top = 5
+ Width = 281
+ Height = 21
+ Margins.Left = 5
+ Margins.Top = 5
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alClient
+ TabOrder = 0
+ TextHint = 'Enter host address'
+ OnChange = edtHostChange
+ ExplicitWidth = 279
+ end
+ object edtPort: TSpinEdit
+ AlignWithMargins = True
+ Left = 291
+ Top = 5
+ Width = 121
+ Height = 22
+ Margins.Left = 0
+ Margins.Top = 5
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alRight
+ MaxValue = 0
+ MinValue = 0
+ TabOrder = 1
+ Value = 16233
+ OnChange = edtPortChange
+ ExplicitLeft = 289
+ end
+ end
+ end
+ object Panel1: TPanel
+ Left = 0
+ Top = 211
+ Width = 527
+ Height = 32
+ Margins.Left = 5
+ Margins.Top = 0
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alBottom
+ BevelOuter = bvNone
+ FullRepaint = False
+ TabOrder = 2
+ ExplicitTop = 203
+ ExplicitWidth = 525
+ object btnSendData: TButton
+ AlignWithMargins = True
+ Left = 5
+ Top = 0
+ Width = 105
+ Height = 27
+ Margins.Left = 5
+ Margins.Top = 0
+ Margins.Right = 0
+ Margins.Bottom = 5
+ Align = alLeft
+ Caption = 'Send'
+ Default = True
+ TabOrder = 0
+ OnClick = btnSendDataClick
+ end
+ object Panel2: TPanel
+ AlignWithMargins = True
+ Left = 110
+ Top = 3
+ Width = 417
+ Height = 26
+ Margins.Left = 0
+ Margins.Right = 0
+ Align = alClient
+ BevelOuter = bvNone
+ FullRepaint = False
+ TabOrder = 1
+ ExplicitWidth = 415
+ object edtDataToSend: TEdit
+ AlignWithMargins = True
+ Left = 5
+ Top = 0
+ Width = 407
+ Height = 21
+ Margins.Left = 5
+ Margins.Top = 0
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alClient
+ TabOrder = 0
+ Text = 'This is some text data'
+ TextHint = 'Enter data to send here'
+ OnEnter = edtDataToSendEnter
+ OnExit = edtDataToSendExit
+ ExplicitWidth = 405
+ end
+ end
+ end
+ object UDPClient: TncUDPClient
+ Family = afIPv6
+ OnReadDatagram = UDPClientReadDatagram
+ Left = 216
+ Top = 96
+ end
+end
diff --git a/Demos/SimpleSockets_UDP/Client/ufrmMain.pas b/Demos/SimpleSockets_UDP/Client/ufrmMain.pas
new file mode 100644
index 0000000..64a8645
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Client/ufrmMain.pas
@@ -0,0 +1,225 @@
+unit ufrmMain;
+
+interface
+
+uses
+{$IFDEF MSWINDOWS}
+ WinApi.Windows, WinApi.Winsock2,
+{$ELSE}
+ Posix.SysSocket, Posix.Unistd,
+{$ENDIF}
+ System.Classes, System.SysUtils, Vcl.Forms, Vcl.Controls, Vcl.StdCtrls,
+ Vcl.ExtCtrls, Vcl.Samples.Spin,
+ System.Diagnostics, ncLines, ncUDPSockets, ncIPUtils;
+
+type
+ TForm1 = class(TForm)
+ memLog: TMemo;
+ pnlToolbar: TPanel;
+ btnActivate: TButton;
+ pnlAddress: TPanel;
+ edtHost: TEdit;
+ edtPort: TSpinEdit;
+ Panel1: TPanel;
+ btnSendData: TButton;
+ Panel2: TPanel;
+ edtDataToSend: TEdit;
+ UDPClient: TncUDPClient;
+ procedure FormCreate(Sender: TObject);
+ procedure FormDestroy(Sender: TObject);
+ procedure btnActivateClick(Sender: TObject);
+ procedure edtHostChange(Sender: TObject);
+ procedure edtPortChange(Sender: TObject);
+ procedure edtDataToSendEnter(Sender: TObject);
+ procedure edtDataToSendExit(Sender: TObject);
+ procedure Log(const AMessage: string);
+ procedure memLogKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
+ procedure btnSendDataClick(Sender: TObject);
+ procedure UDPClientReadDatagram(Sender: TObject; aLine: TncLine;
+ const aBuf: TBytes; aBufCount: Integer;
+ const SenderAddr: TSockAddrStorage);
+
+ private
+ { Private declarations }
+ public
+ { Public declarations }
+ end;
+
+var
+ Form1: TForm1;
+
+implementation
+
+{$R *.dfm}
+
+procedure TForm1.FormCreate(Sender: TObject);
+begin
+ //
+end;
+
+procedure TForm1.FormDestroy(Sender: TObject);
+begin
+ UDPClient.Active := False;
+end;
+
+// *****************************************************************************
+// Start/Stop Main CLient
+// *****************************************************************************
+procedure TForm1.btnActivateClick(Sender: TObject);
+begin
+ if UDPClient.Active then
+ begin
+ // Deactivate the UDP client
+ UDPClient.Active := False;
+ btnActivate.Caption := 'Start UDP Client';
+ Log('UDP Client Deactivated');
+ end
+ else
+ begin
+ // Check if the host field is blank
+ if Trim(edtHost.Text) = '' then
+ begin
+ Log('Host field cannot be blank.');
+ Exit; // Exit the procedure if the host field is blank
+ end;
+
+ try
+ // Set the host from the text field
+ UDPClient.Host := edtHost.Text;
+
+ // Activate the UDP client
+ UDPClient.Active := True;
+ btnActivate.Caption := 'Stop UDP Client';
+ Log('UDP Client Activated');
+ except
+ on E: Exception do
+ Log('Failed to activate UDP Client: ' + E.Message);
+ end;
+ end;
+end;
+
+// *****************************************************************************
+// Change host (server)
+// *****************************************************************************
+procedure TForm1.edtHostChange(Sender: TObject);
+begin
+ try
+ UDPClient.Host := edtHost.Text;
+ except
+ edtHost.OnChange := nil;
+ try
+ edtHost.Text := UDPClient.Host;
+ finally
+ edtHost.OnChange := edtHostChange;
+ end;
+ raise;
+ end;
+end;
+
+// *****************************************************************************
+// Change Main Client port
+// *****************************************************************************
+procedure TForm1.edtPortChange(Sender: TObject);
+begin
+ try
+ UDPClient.Port := edtPort.Value;
+ except
+ edtPort.OnChange := nil;
+ try
+ edtPort.Value := UDPClient.Port;
+ finally
+ edtPort.OnChange := edtPortChange;
+ end;
+ raise;
+ end;
+end;
+
+// *****************************************************************************
+// Data to send
+// *****************************************************************************
+procedure TForm1.edtDataToSendEnter(Sender: TObject);
+begin
+ btnSendData.Default := True;
+end;
+
+procedure TForm1.edtDataToSendExit(Sender: TObject);
+begin
+ btnSendData.Default := False;
+end;
+
+procedure TForm1.btnSendDataClick(Sender: TObject);
+begin
+ try
+ // Ensure the client is active
+ if not UDPClient.Active then
+ begin
+ Log('Cannot send - client not active');
+ Exit;
+ end;
+
+ // Ensure the input field is not empty
+ if Trim(edtDataToSend.Text) = '' then
+ begin
+ Log('Cannot send - Data field cannot be blank.');
+ Exit;
+ end;
+
+ // Send the data if all conditions are met
+ UDPClient.Send(edtDataToSend.Text);
+ Log(Format('Data sent: %s', [edtDataToSend.Text]));
+ except
+ on E: Exception do
+ Log('Error sending: ' + E.Message);
+ end;
+end;
+
+// *****************************************************************************
+// Read Data
+// *****************************************************************************
+procedure TForm1.UDPClientReadDatagram(Sender: TObject; aLine: TncLine;
+ const aBuf: TBytes; aBufCount: Integer; const SenderAddr: TSockAddrStorage);
+var
+ ReceivedData: string;
+ BytesReceived: TBytes;
+ SenderIP: string;
+begin
+ // Convert received data to string
+ ReceivedData := StringOf(Copy(aBuf, 0, aBufCount));
+
+ // Get sender IP address using our utils
+ try
+ SenderIP := TncIPUtils.GetIPFromStorage(SenderAddr);
+ except
+ on E: EIPError do
+ SenderIP := Format('Invalid Address: %s', [E.Message]);
+ end;
+
+ Form1.Log(Format('Received from %s: %s', [SenderIP, ReceivedData]));
+end;
+
+// *****************************************************************************
+// Memo Log
+// *****************************************************************************
+procedure TForm1.Log(const AMessage: string);
+begin
+ TThread.Queue(nil,
+ procedure
+ begin
+ try
+ memLog.Lines.Add(Format('[%s] %s', [FormatDateTime('hh:nn:ss.zzz', Now),
+ AMessage]));
+ finally
+ end;
+ end);
+end;
+
+procedure TForm1.memLogKeyDown(Sender: TObject; var Key: Word;
+Shift: TShiftState);
+begin
+ if (Shift = [ssCtrl]) and (Key = Ord('A')) then
+ memLog.SelectAll
+ else if (Shift = [ssCtrl]) and (Key = Ord('C')) then
+ memLog.CopyToClipboard;
+end;
+
+end.
diff --git a/Demos/SimpleSockets/Srv/Server.dpr b/Demos/SimpleSockets_UDP/Server/Server.dpr
similarity index 80%
rename from Demos/SimpleSockets/Srv/Server.dpr
rename to Demos/SimpleSockets_UDP/Server/Server.dpr
index 2ea1536..5062c31 100644
--- a/Demos/SimpleSockets/Srv/Server.dpr
+++ b/Demos/SimpleSockets_UDP/Server/Server.dpr
@@ -1,17 +1,19 @@
-program Server;
-
-uses
- Vcl.Forms,
- ufrmMain in 'ufrmMain.pas' {frmMain};
-
-{$R *.res}
-
-begin
- {$IFDEF DEBUG}
- ReportMemoryLeaksOnShutdown := True;
- {$ENDIF}
- Application.Initialize;
- Application.MainFormOnTaskbar := True;
- Application.CreateForm(TfrmMain, frmMain);
- Application.Run;
-end.
+program Server;
+
+uses
+ Vcl.Forms,
+ ufrmMain in 'ufrmMain.pas' {frmMain};
+
+{$R *.res}
+
+begin
+ {$IFDEF DEBUG}
+ ReportMemoryLeaksOnShutdown := True;
+ {$ENDIF}
+ Application.Initialize;
+ Application.MainFormOnTaskbar := True;
+ Application.CreateForm(TForm1, Form1);
+ Application.Run;
+end.
+
+
diff --git a/Demos/SimpleSockets_UDP/Server/Server.dproj b/Demos/SimpleSockets_UDP/Server/Server.dproj
new file mode 100644
index 0000000..5dca099
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Server/Server.dproj
@@ -0,0 +1,1170 @@
+
+
+ {B76A70BC-BC2B-42B3-990D-FEC6939EAFD9}
+ 20.2
+ Server.dpr
+ Release
+ DCC32
+ VCL
+ True
+ Win64
+ 3
+ Application
+ Server
+
+
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ Server.exe
+ off
+ vclx;vcl;vclimg;dbrtl;Rave77VCL;bdertl;rtl;vclactnband;xmlrtl;vcldb;vcldbx;vcltouch;dsnap;dsnapcon;TeeUI;TeeDB;Tee;vclib;ibxpress;adortl;IndyCore;IndySystem;IndyProtocols;inet;intrawebdb_100_140;Intraweb_100_140;VclSmp;vclie;websnap;webdsnap;inetdb;inetdbbde;inetdbxpress;soaprtl;vclribbon;dbexpress;DbxCommonDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;DbxClientDriver;DataSnapServer;DBXInterBaseDriver;DBXMySQLDriver;dbxcds;DBXFirebirdDriver;DBXSybaseASEDriver;DBXSybaseASADriver;DBXOracleDriver;DBXMSSQLDriver;DBXInformixDriver;DBXDb2Driver;dclOfficeXP;$(DCC_UsePackage)
+ $(BDSCOMMONDIR)\DCP
+ $(BDSCOMMONDIR)\DCU
+ x86
+ 00400000
+ Server
+ Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)
+ true
+ 1032
+ CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
+ EUREKALOG;$(DCC_Define)
+ 3
+ true
+
+
+ android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
+
+
+ System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
+ Debug
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
+ 1033
+ $(BDS)\bin\default_app.manifest
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ true
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+
+
+ $(BDS)\bin\default_app.manifest
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ true
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+ System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
+ Debug
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+ 1033
+
+
+ false
+ RELEASE;$(DCC_Define)
+ 0
+ 0
+
+
+ true
+ PerMonitorV2
+
+
+ true
+ PerMonitorV2
+ 1033
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+ $(BDS)\bin\delphi_PROJECTICON.ico
+
+
+ false
+ DEBUG;$(DCC_Define)
+
+
+ Debug
+
+
+ true
+ PerMonitorV2
+
+
+ true
+ PerMonitorV2
+
+
+
+ MainSource
+
+
+
+
+
+ Base
+
+
+ Cfg_1
+ Base
+
+
+ Cfg_2
+ Base
+
+
+
+
+ Delphi.Personality.12
+
+
+
+
+ False
+ True
+ False
+
+
+ True
+ False
+ 1
+ 0
+ 0
+ 0
+ False
+ False
+ False
+ False
+ False
+ 1032
+ 1253
+
+
+
+
+ 1.0.0.0
+
+
+
+
+
+ 1.0.0.0
+
+
+
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+
+
+ Server.dpr
+
+
+
+ False
+ True
+ True
+
+
+
+
+ Server.exe
+ true
+
+
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ 0
+
+
+
+
+ res\xml
+ 1
+
+
+ res\xml
+ 1
+
+
+
+
+ library\lib\armeabi
+ 1
+
+
+ library\lib\armeabi
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ library\lib\mips
+ 1
+
+
+ library\lib\mips
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-anydpi-v21
+ 1
+
+
+ res\drawable-anydpi-v21
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\values-v21
+ 1
+
+
+ res\values-v21
+ 1
+
+
+
+
+ res\values-v31
+ 1
+
+
+ res\values-v31
+ 1
+
+
+
+
+ res\drawable-anydpi-v26
+ 1
+
+
+ res\drawable-anydpi-v26
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-anydpi-v33
+ 1
+
+
+ res\drawable-anydpi-v33
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\values-night-v21
+ 1
+
+
+ res\values-night-v21
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+
+
+ res\drawable-ldpi
+ 1
+
+
+ res\drawable-ldpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+
+
+ res\drawable-small
+ 1
+
+
+ res\drawable-small
+ 1
+
+
+
+
+ res\drawable-normal
+ 1
+
+
+ res\drawable-normal
+ 1
+
+
+
+
+ res\drawable-large
+ 1
+
+
+ res\drawable-large
+ 1
+
+
+
+
+ res\drawable-xlarge
+ 1
+
+
+ res\drawable-xlarge
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\drawable-anydpi-v24
+ 1
+
+
+ res\drawable-anydpi-v24
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-night-anydpi-v21
+ 1
+
+
+ res\drawable-night-anydpi-v21
+ 1
+
+
+
+
+ res\drawable-anydpi-v31
+ 1
+
+
+ res\drawable-anydpi-v31
+ 1
+
+
+
+
+ res\drawable-night-anydpi-v31
+ 1
+
+
+ res\drawable-night-anydpi-v31
+ 1
+
+
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ 0
+
+
+
+
+ Contents\MacOS
+ 1
+ .framework
+
+
+ Contents\MacOS
+ 1
+ .framework
+
+
+ Contents\MacOS
+ 1
+ .framework
+
+
+ 0
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ 0
+ .dll;.bpl
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ 0
+ .bpl
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ Contents\Resources\StartUp\
+ 0
+
+
+ Contents\Resources\StartUp\
+ 0
+
+
+ Contents\Resources\StartUp\
+ 0
+
+
+ 0
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+
+
+ Contents
+ 1
+
+
+ Contents
+ 1
+
+
+ Contents
+ 1
+
+
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ 0
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen
+ 64
+
+
+ ..\$(PROJECTNAME).launchscreen
+ 64
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 12
+
+
+
+
diff --git a/Demos/SimpleSockets_UDP/Server/Server.dproj.local b/Demos/SimpleSockets_UDP/Server/Server.dproj.local
new file mode 100644
index 0000000..c6ab0d5
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Server/Server.dproj.local
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+ 2025/01/14 22:17:15.000.403,=D:\_Delphi\_Library\Netcom7\Demos\SimpleSockets_UDP\Server\Unit1.pas
+ 2025/01/14 22:17:30.000.252,D:\_Delphi\_Library\Netcom7\Demos\SimpleSockets_UDP\Server\uMainServer.pas=D:\_Delphi\_Library\Netcom7\Demos\SimpleSockets_UDP\Server\Unit1.pas
+ 2025/01/16 20:08:59.000.762,D:\_Delphi\_Library\NetCom7\Demos\SimpleSockets_UDP_v2\Server\uMainServer.pas=
+
+
diff --git a/Demos/SimpleSockets_UDP/Server/Server.dsk b/Demos/SimpleSockets_UDP/Server/Server.dsk
new file mode 100644
index 0000000..78670b2
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Server/Server.dsk
@@ -0,0 +1,768 @@
+[Closed Files]
+File_0=TSourceModule,'C:\Users\Programmer\Documents\Development\Components\NetCom7\Source\ncSockets.pas',0,1,1081,1,1097,0,0,,
+File_1=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\SOURCE\VCL\Vcl.Forms.pas',0,1,1,15,10,0,0,{{1755,4}
+File_2=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\SOURCE\VCL\Vcl.StdCtrls.pas',0,1,1,6,10,0,0,{{1657,4}
+File_3=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\source\rtl\common\System.Classes.pas',0,1,1,6,10,0,0,,
+File_4=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\SOURCE\RTL\SYS\System.SysUtils.pas',0,1,1,6,16,0,0,,
+File_5=TSourceModule,'c:\program files (x86)\embarcadero\studio\20.0\source\rtl\win\Winapi.Messages.pas',0,1,1,6,19,0,0,,
+File_6=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncSockets.pas',0,1,1241,1,1260,0,0,,{1
+File_7=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncSources.pas',0,1,738,3,762,0,0,,{1
+File_8=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\DirectPanel\dpDXAPIHelpers.pas',0,1,1,1,5,0,0,,{1
+File_9=TSourceModule,'C:\Users\BDemos\Documents\RAD Studio\Components\NetCom7\Source\ncThreads.pas',0,1,88,13,95,0,0,,
+
+[Modules]
+Module0=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas
+Module1=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\Server.dproj
+Count=2
+EditWindowCount=1
+
+[C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas]
+ModuleType=TSourceModule
+
+[C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\Server.dproj]
+ModuleType=TBaseProject
+
+[EditWindow0]
+ViewCount=2
+CurrentEditView=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas
+View0=0
+View1=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=9900
+Height=8837
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=9900
+ClientHeight=8837
+DockedToMainForm=1
+BorlandEditorCodeExplorer=BorlandEditorCodeExplorer@EditWindow0
+TopPanelSize=0
+LeftPanelSize=1894
+LeftPanelClients=PropertyInspector,DockSite3
+LeftPanelData=000008000101000000008E120000000000000166070000000000000100000000530E000009000000446F636B53697465330100000000FC2000001100000050726F7065727479496E73706563746F72FFFFFFFF
+RightPanelSize=1525
+RightPanelClients=DockSite2,DockSite4
+RightPanelData=000008000101000000008E1200000000000001F50500000000000001000000004612000009000000446F636B53697465320100000000FC20000009000000446F636B5369746534FFFFFFFF
+BottomPanelSize=0
+BottomPanelClients=DockSite1,MessageView
+BottomPanelData=0000080001020200000009000000446F636B53697465310F0000004D65737361676556696577466F726D1534000000000000022A06000000000000FFFFFFFF
+BottomMiddlePanelSize=0
+BottomMiddlePanelClients=DockSite0,GraphDrawingModel
+BottomMiddelPanelData=0000080001020200000009000000446F636B536974653010000000477261706844726177696E67566965779A1D00000000000002F206000000000000FFFFFFFF
+
+[View0]
+CustomEditViewType=TEditView
+Module=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\Server.dpr
+CursorX=20
+CursorY=5
+TopLine=1
+LeftCol=1
+Elisions=
+Bookmarks=
+EditViewName=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\Server.dpr
+
+[View1]
+CustomEditViewType=TEditView
+Module=C:\Users\Programmer\Documents\Development\Components\NetCom7\Demos\SimpleSockets\Srv\ufrmMain.pas
+CursorX=11
+CursorY=6
+TopLine=1
+LeftCol=1
+Elisions=
+Bookmarks=
+EditViewName=Borland.FormDesignerView
+
+[UndockedDesigner]
+Count=0
+
+[Watches]
+Count=0
+
+[WatchWindow]
+WatchColumnWidth=120
+WatchShowColumnHeaders=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=209
+LRDockWidth=13600
+Dockable=1
+StayOnTop=0
+
+[Breakpoints]
+Count=0
+
+[EmbarcaderoWin32Debugger_AddressBreakpoints]
+Count=0
+
+[EmbarcaderoWin64Debugger_AddressBreakpoints]
+Count=0
+
+[EmbarcaderoAndroid32Debugger_AddressBreakpoints]
+Count=0
+
+[EmbarcaderoAndroid64Debugger_AddressBreakpoints]
+Count=0
+
+[Main Window]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=0
+State=2
+Left=144
+Top=279
+Width=8931
+Height=8523
+MaxLeft=-6
+MaxTop=-12
+MaxWidth=8931
+MaxHeight=8523
+ClientWidth=10025
+ClientHeight=9744
+BottomPanelSize=8444
+BottomPanelClients=EditWindow0
+BottomPanelData=0000080000000000000000000000000000000000000000000000000100000000000000000C0000004564697457696E646F775F30FFFFFFFF
+
+[ProjectManager]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=5895
+LRDockWidth=2350
+Dockable=1
+StayOnTop=0
+
+[MessageView]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2769
+Height=1419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2769
+ClientHeight=1419
+TBDockHeight=1419
+LRDockWidth=2769
+Dockable=1
+StayOnTop=0
+
+[ToolForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=3616
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=3616
+TBDockHeight=7151
+LRDockWidth=2000
+Dockable=1
+StayOnTop=0
+
+[ClipboardHistory]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=0
+State=0
+Left=0
+Top=0
+Width=2338
+Height=5174
+MaxLeft=-6
+MaxTop=-12
+ClientWidth=2262
+ClientHeight=4733
+TBDockHeight=5174
+LRDockWidth=2338
+Dockable=1
+StayOnTop=0
+
+[PropertyInspector]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=358
+Width=1894
+Height=4674
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1894
+ClientHeight=4674
+TBDockHeight=9012
+LRDockWidth=1894
+Dockable=1
+StayOnTop=0
+SplitPos=111
+
+[PropInspDesignerSelection]
+ArrangeBy=Name
+SelectedItem=Action,
+ExpandedItems=LiveBindings=0,"LiveBindings Designer=0",Margins=0,ActiveControl=0,Anchors=0,BorderIcons=0
+
+[frmDesignPreview]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=5953
+LRDockWidth=2512
+Dockable=1
+StayOnTop=0
+
+[TemplateView]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=0
+Top=0
+Width=275
+Height=360
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=275
+ClientHeight=360
+TBDockHeight=360
+LRDockWidth=275
+Dockable=1
+StayOnTop=0
+Name=120
+Description=334
+filter=1
+
+[DebugLogView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=407
+LRDockWidth=4950
+Dockable=1
+StayOnTop=0
+
+[ThreadStatusWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=209
+LRDockWidth=7406
+Dockable=1
+StayOnTop=0
+Column0Width=145
+Column1Width=100
+Column2Width=115
+Column3Width=252
+
+[LocalVarsWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=1535
+LRDockWidth=3481
+Dockable=1
+StayOnTop=0
+
+[CallStackWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=2070
+LRDockWidth=3481
+Dockable=1
+StayOnTop=0
+
+[PatchForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1151
+TBDockHeight=2500
+LRDockWidth=3400
+Dockable=1
+StayOnTop=0
+
+[FindReferencsForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1151
+TBDockHeight=2314
+LRDockWidth=2825
+Dockable=1
+StayOnTop=0
+
+[RefactoringForm]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1151
+TBDockHeight=3209
+LRDockWidth=2825
+Dockable=1
+StayOnTop=0
+
+[ToDo List]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1140
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1140
+TBDockHeight=1151
+LRDockWidth=3675
+Dockable=1
+StayOnTop=0
+Column0Width=314
+Column1Width=30
+Column2Width=150
+Column3Width=172
+Column4Width=129
+SortOrder=4
+ShowHints=1
+ShowChecked=1
+
+[DataExplorerContainer]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=4884
+LRDockWidth=7150
+Dockable=1
+StayOnTop=0
+
+[GraphDrawingModel]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2856
+Height=3209
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2856
+ClientHeight=3209
+TBDockHeight=3209
+LRDockWidth=2856
+Dockable=1
+StayOnTop=0
+
+[ClassBrowserTool]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=-318
+Top=-363
+Width=1850
+Height=3140
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1850
+ClientHeight=3140
+TBDockHeight=3140
+LRDockWidth=1850
+Dockable=1
+StayOnTop=0
+
+[MetricsView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1163
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1163
+TBDockHeight=4837
+LRDockWidth=3562
+Dockable=1
+StayOnTop=0
+
+[QAView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=2338
+Height=1163
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1163
+TBDockHeight=4837
+LRDockWidth=3562
+Dockable=1
+StayOnTop=0
+
+[BreakpointWindow]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=3825
+Height=1093
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1093
+TBDockHeight=1547
+LRDockWidth=8744
+Dockable=1
+StayOnTop=0
+Column0Width=200
+Column1Width=75
+Column2Width=200
+Column3Width=200
+Column4Width=200
+Column5Width=75
+Column6Width=75
+
+[StructureView]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1894
+Height=3419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1894
+ClientHeight=3419
+TBDockHeight=3674
+LRDockWidth=1894
+Dockable=1
+StayOnTop=0
+
+[fmGrepResults]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=0
+State=0
+Left=0
+Top=0
+Width=2575
+Height=4372
+MaxLeft=-6
+MaxTop=-12
+ClientWidth=2475
+ClientHeight=3919
+TBDockHeight=4372
+LRDockWidth=2575
+Dockable=1
+StayOnTop=0
+
+[ModelViewTool]
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=0
+Width=1525
+Height=4151
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4151
+TBDockHeight=4884
+LRDockWidth=5306
+Dockable=1
+StayOnTop=0
+
+[BorlandEditorCodeExplorer@EditWindow0]
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=0
+State=0
+Left=0
+Top=0
+Width=1825
+Height=6174
+MaxLeft=-6
+MaxTop=-12
+ClientWidth=1725
+ClientHeight=5721
+TBDockHeight=6174
+LRDockWidth=1825
+Dockable=1
+StayOnTop=0
+
+[DockHosts]
+DockHostCount=5
+
+[DockSite0]
+HostDockSite=DockBottomCenterPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=8
+Top=8
+Width=2338
+Height=1477
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=2338
+ClientHeight=1477
+TBDockHeight=1477
+LRDockWidth=2338
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=RefactoringForm
+TabDockClients=RefactoringForm,PatchForm,FindReferencsForm,ToDo List,MetricsView,QAView
+
+[DockSite1]
+HostDockSite=DockBottomPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=0
+Docked=1
+State=0
+Left=8
+Top=8
+Width=3825
+Height=1419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=3825
+ClientHeight=1419
+TBDockHeight=1419
+LRDockWidth=3825
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=DebugLogView
+TabDockClients=DebugLogView,BreakpointWindow,ThreadStatusWindow,CallStackWindow,WatchWindow,LocalVarsWindow
+
+[DockSite2]
+HostDockSite=DockRightPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=28
+Width=1525
+Height=4477
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=4477
+TBDockHeight=9012
+LRDockWidth=1525
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=ProjectManager
+TabDockClients=ProjectManager,ModelViewTool,DataExplorerContainer,frmDesignPreview
+
+[DockSite3]
+HostDockSite=DockLeftPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=28
+Width=1894
+Height=3419
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1894
+ClientHeight=3419
+TBDockHeight=9012
+LRDockWidth=1894
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=StructureView
+TabDockClients=StructureView,ClassBrowserTool
+
+[DockSite4]
+HostDockSite=DockRightPanel
+DockSiteType=1
+PercentageSizes=1
+Create=1
+Visible=1
+Docked=1
+State=0
+Left=0
+Top=449
+Width=1525
+Height=3616
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1525
+ClientHeight=3616
+TBDockHeight=9012
+LRDockWidth=1525
+Dockable=1
+StayOnTop=0
+TabPosition=1
+ActiveTabID=ToolForm
+TabDockClients=ToolForm,TemplateView
+
diff --git a/Demos/SimpleSockets_UDP/Server/Server.identcache b/Demos/SimpleSockets_UDP/Server/Server.identcache
new file mode 100644
index 0000000..532a302
Binary files /dev/null and b/Demos/SimpleSockets_UDP/Server/Server.identcache differ
diff --git a/Demos/SimpleSockets_UDP/Server/Server.res b/Demos/SimpleSockets_UDP/Server/Server.res
new file mode 100644
index 0000000..0af1ebd
Binary files /dev/null and b/Demos/SimpleSockets_UDP/Server/Server.res differ
diff --git a/Demos/SimpleSockets_UDP/Server/Server.skincfg b/Demos/SimpleSockets_UDP/Server/Server.skincfg
new file mode 100644
index 0000000..0f00ce7
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Server/Server.skincfg
@@ -0,0 +1,33 @@
+[ExpressSkins]
+Default=1
+ShowNotifications=1
+Enabled=1
+dxSkinBlack=1
+dxSkinBlue=0
+dxSkinCaramel=0
+dxSkinCoffee=0
+dxSkinDarkRoom=0
+dxSkinDarkSide=1
+dxSkinFoggy=0
+dxSkinGlassOceans=0
+dxSkiniMaginary=0
+dxSkinLilian=0
+dxSkinLiquidSky=0
+dxSkinLondonLiquidSky=0
+dxSkinMcSkin=0
+dxSkinMoneyTwins=0
+dxSkinOffice2007Black=1
+dxSkinOffice2007Blue=0
+dxSkinOffice2007Green=0
+dxSkinOffice2007Pink=0
+dxSkinOffice2007Silver=1
+dxSkinPumpkin=0
+dxSkinSeven=0
+dxSkinSharp=0
+dxSkinSilver=0
+dxSkinSpringTime=0
+dxSkinStardust=0
+dxSkinSummer2008=0
+dxSkinsDefaultPainters=0
+dxSkinValentine=0
+dxSkinXmas2008Blue=0
diff --git a/Demos/SimpleSockets_UDP/Server/Server_Icon.ico b/Demos/SimpleSockets_UDP/Server/Server_Icon.ico
new file mode 100644
index 0000000..379ec80
Binary files /dev/null and b/Demos/SimpleSockets_UDP/Server/Server_Icon.ico differ
diff --git a/Demos/SimpleSockets_UDP/Server/ufrmMain.dfm b/Demos/SimpleSockets_UDP/Server/ufrmMain.dfm
new file mode 100644
index 0000000..833567c
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Server/ufrmMain.dfm
@@ -0,0 +1,98 @@
+object Form1: TForm1
+ Left = 0
+ Top = 0
+ Caption = 'UDPServer'
+ ClientHeight = 244
+ ClientWidth = 527
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ Position = poScreenCenter
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ TextHeight = 13
+ object memLog: TMemo
+ AlignWithMargins = True
+ Left = 5
+ Top = 37
+ Width = 517
+ Height = 202
+ Margins.Left = 5
+ Margins.Top = 0
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alClient
+ ReadOnly = True
+ ScrollBars = ssVertical
+ TabOrder = 0
+ OnKeyDown = memLogKeyDown
+ ExplicitWidth = 515
+ ExplicitHeight = 194
+ end
+ object pnlToolbar: TPanel
+ Left = 0
+ Top = 0
+ Width = 527
+ Height = 37
+ Align = alTop
+ BevelOuter = bvNone
+ FullRepaint = False
+ TabOrder = 1
+ ExplicitWidth = 525
+ object btnActivate: TButton
+ AlignWithMargins = True
+ Left = 5
+ Top = 5
+ Width = 105
+ Height = 27
+ Margins.Left = 5
+ Margins.Top = 5
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alLeft
+ Caption = 'Start UDP Server'
+ TabOrder = 0
+ OnClick = btnActivateClick
+ end
+ object pblPort: TPanel
+ AlignWithMargins = True
+ Left = 115
+ Top = 3
+ Width = 412
+ Height = 31
+ Margins.Left = 0
+ Margins.Right = 0
+ Align = alClient
+ BevelOuter = bvNone
+ FullRepaint = False
+ TabOrder = 1
+ ExplicitWidth = 410
+ object edtPort: TSpinEdit
+ AlignWithMargins = True
+ Left = 0
+ Top = 5
+ Width = 121
+ Height = 22
+ Margins.Left = 0
+ Margins.Top = 5
+ Margins.Right = 5
+ Margins.Bottom = 5
+ Align = alLeft
+ MaxValue = 0
+ MinValue = 0
+ TabOrder = 0
+ Value = 16233
+ OnChange = edtPortChange
+ end
+ end
+ end
+ object UDPServer: TncUDPServer
+ Family = afIPv6
+ OnReadDatagram = UDPServerReadDatagram
+ Left = 232
+ Top = 104
+ end
+end
diff --git a/Demos/SimpleSockets_UDP/Server/ufrmMain.pas b/Demos/SimpleSockets_UDP/Server/ufrmMain.pas
new file mode 100644
index 0000000..162f7f0
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/Server/ufrmMain.pas
@@ -0,0 +1,170 @@
+unit ufrmMain;
+
+interface
+
+uses
+{$IFDEF MSWINDOWS}
+ WinApi.Windows, WinApi.Winsock2,
+{$ELSE}
+ Posix.SysSocket, Posix.Unistd,
+{$ENDIF}
+ System.Classes, System.SysUtils, Vcl.Forms, Vcl.Controls, Vcl.StdCtrls,
+ Vcl.ExtCtrls, Vcl.Samples.Spin, System.Diagnostics,
+ ncLines, ncUDPSockets, ncIPUtils;
+
+type
+ TForm1 = class(TForm)
+ memLog: TMemo;
+ pnlToolbar: TPanel;
+ btnActivate: TButton;
+ pblPort: TPanel;
+ edtPort: TSpinEdit;
+ UDPServer: TncUDPServer;
+ procedure FormCreate(Sender: TObject);
+ procedure FormDestroy(Sender: TObject);
+ procedure btnActivateClick(Sender: TObject);
+ procedure Log(const AMessage: string);
+ procedure memLogKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
+ procedure edtPortChange(Sender: TObject);
+ procedure SendToClient(const Data: string; const DestAddr: TSockAddrStorage);
+ procedure UDPServerReadDatagram(Sender: TObject; aLine: TncLine;
+ const aBuf: TBytes; aBufCount: Integer;
+ const SenderAddr: TSockAddrStorage);
+ public
+ end;
+
+var
+ Form1: TForm1;
+
+implementation
+
+{$R *.dfm}
+
+procedure TForm1.FormCreate(Sender: TObject);
+begin
+//
+end;
+
+procedure TForm1.FormDestroy(Sender: TObject);
+begin
+ UDPServer.Active := False;
+end;
+
+// *****************************************************************************
+// Start/Stop Main CLient
+// *****************************************************************************
+procedure TForm1.btnActivateClick(Sender: TObject);
+begin
+ if UDPServer.Active then
+ begin
+ // Deactivate the UDP client
+ UDPServer.Active := False;
+ btnActivate.Caption := 'Start UDP Server';
+ Form1.Log('UDP Server Deactivated');
+ end
+ else
+ begin
+ try
+ // Activate the UDP client
+ UDPServer.Active := True;
+ btnActivate.Caption := 'Stop UDP Server';
+ Form1.Log('UDP Server Activated');
+ except
+ on E: Exception do
+ Form1.Log('Failed to activate UDP Server: ' + E.Message);
+ end;
+ end;
+end;
+
+// *****************************************************************************
+// Change Main Server port
+// *****************************************************************************
+procedure TForm1.edtPortChange(Sender: TObject);
+begin
+ try
+ UDPServer.Port := edtPort.Value;
+ except
+ edtPort.OnChange := nil;
+ try
+ edtPort.Value := UDPServer.Port;
+ finally
+ edtPort.OnChange := edtPortChange;
+ end;
+ raise;
+ end;
+end;
+
+// *****************************************************************************
+// SendToClient
+// *****************************************************************************
+procedure TForm1.SendToClient(const Data: string; const DestAddr: TSockAddrStorage);
+var
+ SenderIP: string;
+begin
+ if not UDPServer.Active then
+ Exit;
+
+ try
+ // Get IP address using our utils
+ SenderIP := TncIPUtils.GetIPFromStorage(DestAddr);
+
+ // Send the data - pass TSockAddrStorage directly
+ UDPServer.SendTo(BytesOf(Data), DestAddr);
+
+ Form1.Log(Format('Sent to %s: %s', [SenderIP, Data]));
+ except
+ on E: Exception do
+ Form1.Log('Error sending data: ' + E.Message);
+ end;
+end;
+
+// *****************************************************************************
+// Read Data
+// *****************************************************************************
+procedure TForm1.UDPServerReadDatagram(Sender: TObject; aLine: TncLine;
+ const aBuf: TBytes; aBufCount: Integer; const SenderAddr: TSockAddrStorage);
+var
+ ReceivedData: string;
+ SenderIP: string;
+begin
+ try
+ // Convert received data to string
+ ReceivedData := StringOf(Copy(aBuf, 0, aBufCount));
+
+ // Get sender IP address using our utils
+ SenderIP := TncIPUtils.GetIPFromStorage(SenderAddr);
+
+ // Log and echo
+ Form1.Log(Format('Received from %s: %s', [SenderIP, ReceivedData]));
+ SendToClient('Echo: ' + ReceivedData, SenderAddr);
+ except
+ on E: Exception do
+ Form1.Log(Format('Error processing datagram: %s', [E.Message]));
+ end;
+end;
+
+// *****************************************************************************
+// Memo Log
+// *****************************************************************************
+procedure TForm1.Log(const AMessage: string);
+begin
+ TThread.Queue(nil,
+ procedure
+ begin
+ try
+ memLog.Lines.Add(Format('[%s] %s', [FormatDateTime('hh:nn:ss.zzz', Now),
+ AMessage]));
+ finally
+ end;
+ end);
+end;
+
+procedure TForm1.memLogKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
+begin
+ if (Shift = [ssCtrl]) and (Key = Ord('A')) then
+ memLog.SelectAll
+ else if (Shift = [ssCtrl]) and (Key = Ord('C')) then
+ memLog.CopyToClipboard;
+end;
+
+end.
diff --git a/Demos/SimpleSockets_UDP/SimpleSockets_UDP.groupproj b/Demos/SimpleSockets_UDP/SimpleSockets_UDP.groupproj
new file mode 100644
index 0000000..29ca13f
--- /dev/null
+++ b/Demos/SimpleSockets_UDP/SimpleSockets_UDP.groupproj
@@ -0,0 +1,48 @@
+
+
+ {7EB9A25E-4A42-4DE8-919E-70124E14615F}
+
+
+
+
+
+
+
+
+
+
+ Default.Personality.12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Demos/SimpleSockets_UDP/SimpleSockets_UDPv4.PNG b/Demos/SimpleSockets_UDP/SimpleSockets_UDPv4.PNG
new file mode 100644
index 0000000..15bb068
Binary files /dev/null and b/Demos/SimpleSockets_UDP/SimpleSockets_UDPv4.PNG differ
diff --git a/Demos/SimpleSockets_UDP/SimpleSockets_UDPv6.PNG b/Demos/SimpleSockets_UDP/SimpleSockets_UDPv6.PNG
new file mode 100644
index 0000000..4abb230
Binary files /dev/null and b/Demos/SimpleSockets_UDP/SimpleSockets_UDPv6.PNG differ
diff --git a/NetCom7.dpk b/NetCom7.dpk
index 6dccda7..2446bd4 100644
--- a/NetCom7.dpk
+++ b/NetCom7.dpk
@@ -78,7 +78,9 @@ contains
ncEncTea in 'Source\Encryption\ncEncTea.pas',
ncEncTiger in 'Source\Encryption\ncEncTiger.pas',
ncEncTwofish in 'Source\Encryption\ncEncTwofish.pas',
- ncPendingCommandsList in 'Source\ncPendingCommandsList.pas';
+ ncPendingCommandsList in 'Source\ncPendingCommandsList.pas',
+ ncUDPSockets in 'Source\ncUDPSockets.pas',
+ ncIPUtils in 'Source\ncIPUtils.pas';
end.
diff --git a/NetCom7.dproj b/NetCom7.dproj
index 5dfc635..519880e 100644
--- a/NetCom7.dproj
+++ b/NetCom7.dproj
@@ -2,14 +2,15 @@
{57C69AC0-7B5F-43DD-957C-8CC07D9D9092}
NetCom7.dpk
- 19.5
+ 20.2
Release
DCC32
None
True
Win32
- 693267
+ 1741843
Package
+ NetCom7
true
@@ -54,6 +55,11 @@
Base
true
+
+ true
+ Base
+ true
+
true
Base
@@ -142,13 +148,13 @@
android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar
rtl;dbrtl;$(DCC_UsePackage)
- package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=
+ package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=;minSdkVersion=23;targetSdkVersion=34
$(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
Debug
false
- package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=
+ package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=;minSdkVersion=23;targetSdkVersion=34
Debug
false
true
@@ -172,12 +178,12 @@
$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png
- CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false
+ CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface
Debug
false
- CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false
+ CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface
Debug
false
@@ -204,6 +210,13 @@
false
true
+
+ Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
+ Debug
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+ 1033
+ true
+
false
false
@@ -221,8 +234,8 @@
1033
- CompanyName=;FileVersion=7.2.0.577;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=7.2;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
- 577
+ CompanyName=;FileVersion=7.2.0.636;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=7.2;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
+ 636
2
false
true
@@ -312,10 +325,20 @@
+
+
BITMAP
TNCICON
+
+ BITMAP
+ TNCUDPCLIENT
+
+
+ BITMAP
+ TNCUDPSERVER
+
Base
@@ -367,7 +390,10 @@
- Microsoft Office 2000 Sample Automation Server Wrapper Components
+ Embarcadero C++Builder Office 2000 Servers Package
+ Embarcadero C++Builder Office XP Servers Package
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+ Microsoft Office XP Sample Automation Server Wrapper Components
NetCom7.dpk
@@ -378,12 +404,14 @@
True
True
True
+ False
True
True
True
True
+ True
-
+
true
@@ -400,6 +428,12 @@
+
+
+ NetCom7.bpl
+ true
+
+
1
@@ -408,16 +442,6 @@
0
-
-
- classes
- 64
-
-
- classes
- 64
-
-
res\xml
@@ -428,12 +452,6 @@
1
-
-
- library\lib\armeabi-v7a
- 1
-
-
library\lib\armeabi
@@ -486,6 +504,16 @@
1
+
+
+ res\drawable-anydpi-v21
+ 1
+
+
+ res\drawable-anydpi-v21
+ 1
+
+
res\values
@@ -506,6 +534,66 @@
1
+
+
+ res\values-v31
+ 1
+
+
+ res\values-v31
+ 1
+
+
+
+
+ res\drawable-anydpi-v26
+ 1
+
+
+ res\drawable-anydpi-v26
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-anydpi-v33
+ 1
+
+
+ res\drawable-anydpi-v33
+ 1
+
+
res\values
@@ -516,6 +604,16 @@
1
+
+
+ res\values-night-v21
+ 1
+
+
+ res\values-night-v21
+ 1
+
+
res\drawable
@@ -686,6 +784,56 @@
1
+
+
+ res\drawable-anydpi-v24
+ 1
+
+
+ res\drawable-anydpi-v24
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-night-anydpi-v21
+ 1
+
+
+ res\drawable-night-anydpi-v21
+ 1
+
+
+
+
+ res\drawable-anydpi-v31
+ 1
+
+
+ res\drawable-anydpi-v31
+ 1
+
+
+
+
+ res\drawable-night-anydpi-v31
+ 1
+
+
+ res\drawable-night-anydpi-v31
+ 1
+
+
1
@@ -863,6 +1011,9 @@
1
+
+ 1
+
@@ -1124,6 +1275,7 @@
+
12
diff --git a/NetCom7.dproj.local b/NetCom7.dproj.local
index 6a2e1d7..6340550 100644
--- a/NetCom7.dproj.local
+++ b/NetCom7.dproj.local
@@ -6,8 +6,8 @@
2020/08/08 06:05:23.000.402,=C:\Users\Programmer\Documents\Development\Components\NetCom7\Source\ncSocketList.pas
2020/08/08 06:14:41.000.027,=C:\Users\Programmer\Documents\Development\Components\NetCom7\Unit1.pas
- 2020/08/08 06:15:03.000.683,C:\Users\Programmer\Documents\Development\Components\NetCom7\Source\ncLine.pas=C:\Users\Programmer\Documents\Development\Components\NetCom7\Unit1.pas
- 2020/08/08 07:50:30.000.380,C:\Users\Programmer\Documents\Development\Components\NetCom7\Source\ncLine.pas=C:\Users\Programmer\Documents\Development\Components\NetCom7\Source\ncLines.pas
+ 2020/08/08 06:15:03.000.683,C:\Users\Programmer\Documents\Development\Components\NetCom7\Unit1.pas=C:\Users\Programmer\Documents\Development\Components\NetCom7\Source\ncLine.pas
+ 2020/08/08 07:50:30.000.380,C:\Users\Programmer\Documents\Development\Components\NetCom7\Source\ncLines.pas=C:\Users\Programmer\Documents\Development\Components\NetCom7\Source\ncLine.pas
2020/08/10 13:33:07.000.316,=C:\Users\Programmer\Documents\Development\Components\NetCom7\Icons\TncClientSource.png
2020/08/10 13:45:09.000.739,C:\Users\Programmer\Documents\Development\Components\NetCom7\Icons\TncClientSource.png=
2020/08/10 13:45:27.000.192,=C:\Users\Programmer\Documents\Development\Components\NetCom7\Icons\TncClientSource.png
@@ -15,5 +15,17 @@
2020/08/10 13:50:07.000.192,=C:\Users\Programmer\Documents\Development\Components\NetCom7\Icons\TncIcon.bmp
2020/08/10 14:10:53.000.681,=C:\Users\Programmer\Documents\Development\Components\NetCom7\PaletteIcons\TncIcon.bmp
2020/08/11 19:21:43.000.342,=C:\Users\Programmer\Documents\Development\Components\NetCom7\Source\ncPendingCommandsList.pas
+ 2025/01/15 16:33:36.000.508,=D:\_Delphi\_Library\NetCom7\Unit1.pas
+ 2025/01/15 16:35:56.000.977,=D:\_Delphi\_Library\NetCom7\Source\ncUDPSockets.pas
+ 2025/01/15 20:33:31.000.011,=D:\_Delphi\_Library\NetCom7 - Copie\PaletteIcons\tncudpclient_32x32.bmp
+ 2025/01/15 20:33:39.000.888,=D:\_Delphi\_Library\NetCom7 - Copie\PaletteIcons\tncudpserver_32x32.bmp
+ 2025/01/15 21:36:54.000.533,=D:\_Delphi\_Library\NetCom7\PaletteIcons\tncudpserver_32x32.bmp
+ 2025/01/15 21:36:59.000.040,=D:\_Delphi\_Library\NetCom7\PaletteIcons\tncudpclient_32x32.bmp
+ 2025/01/15 21:38:09.000.173,D:\_Delphi\_Library\NetCom7\PaletteIcons\tncudpserver_32x32.bmp=
+ 2025/01/15 21:38:44.000.282,D:\_Delphi\_Library\NetCom7\PaletteIcons\tncudpclient_32x32.bmp=
+ 2025/01/16 20:01:26.000.332,=D:\_Delphi\_Library\NetCom7\PaletteIcons\tncudpclient.bmp
+ 2025/01/16 20:01:26.000.367,=D:\_Delphi\_Library\NetCom7\PaletteIcons\tncudpserver.bmp
+ 2025/01/21 00:15:32.000.432,=D:\_Delphi\_Library\Netcom7\Source\ncIPv6Utils.pas
+ 2025/01/21 00:36:50.000.240,D:\_Delphi\_Library\Netcom7\Source\ncIPv6Utils.pas=D:\_Delphi\_Library\Netcom7\Source\ncIPUtils.pas
diff --git a/NetCom7.dres b/NetCom7.dres
index 42500fd..d5a96db 100644
Binary files a/NetCom7.dres and b/NetCom7.dres differ
diff --git a/NetCom7.identcache b/NetCom7.identcache
index ae7acea..3d957b7 100644
Binary files a/NetCom7.identcache and b/NetCom7.identcache differ
diff --git a/NetCom7.res b/NetCom7.res
index 762c09e..c3964ed 100644
Binary files a/NetCom7.res and b/NetCom7.res differ
diff --git a/NetCom7Resource.rc b/NetCom7Resource.rc
index 5ccefa7..c506c76 100644
--- a/NetCom7Resource.rc
+++ b/NetCom7Resource.rc
@@ -1 +1,3 @@
TNCICON BITMAP "PaletteIcons\\TncIcon.bmp"
+TNCUDPCLIENT BITMAP "PaletteIcons\\tncudpclient.bmp"
+TNCUDPSERVER BITMAP "PaletteIcons\\tncudpserver.bmp"
diff --git a/PaletteIcons/tncudpclient.bmp b/PaletteIcons/tncudpclient.bmp
new file mode 100644
index 0000000..e7b7e39
Binary files /dev/null and b/PaletteIcons/tncudpclient.bmp differ
diff --git a/PaletteIcons/tncudpserver.bmp b/PaletteIcons/tncudpserver.bmp
new file mode 100644
index 0000000..aa3e078
Binary files /dev/null and b/PaletteIcons/tncudpserver.bmp differ
diff --git a/README.md b/README.md
index 3daf62b..5e7c452 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,33 @@
# NetCom7
+
The fastest communications possible.
-This is version 7.2 of the NetCom package. In this version, the NetCom package is now multi-platform!
-You can compile your apps under all platforms in FireMonkey!
+This is an updated version of the NetCom7 package, now with enhanced **UDP** & **IPV6** support and improved cross-platform capabilities! You can compile your apps under all platforms in FireMonkey!
+
+## Recent Updates
+
+### New Components
+The **UDP** components can be dragged from the palette and customized in the object inspector with the following properties:
+- Broadcast capabilities
+- Buffer size customization
+
+
+
+### IPV6
+
+TCP v4 / TCP v6 / UDP v4 / UDP v6 are now avaible.
+
+⚠️ Client and Server must use the same familly version (no dual-stack sockets).
+
+
+
+
+
+### Demo Updates
+- Added new `SimpleSockets_UDP` demo
+- Updated the `SimpleSockets` demo
+
+
This set of components is the fastest possible implementation of socket communications, in any language; this is an extremely optimised code on TCP/IP sockets. Forget using a thread per connection: With this suite you can have as many concurrent connections to your server as you like. Threads are used per request and not per connection, and are maintained in a very fast thread pool class.
diff --git a/Source/NetComRegister.pas b/Source/NetComRegister.pas
index e341655..984b11a 100644
--- a/Source/NetComRegister.pas
+++ b/Source/NetComRegister.pas
@@ -1,21 +1,10 @@
unit NetComRegister;
-// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// NetCom7 Package
-// 13 Dec 2010, 12/8/2020
-//
-// Written by Demos Bill
-// VasDemos@yahoo.co.uk
-//
-// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
interface
uses
WinApi.Windows, System.Classes, System.SysUtils, ToolsAPI, DesignIntf, DesignEditors,
-
- ncSockets, ncSources, ncCommandHandlers, ncDBSrv, ncDBCnt;
+ ncSockets, ncSources, ncCommandHandlers, ncDBSrv, ncDBCnt, ncUDPSockets; // Added ncUDPSockets
type
TncTCPSocketDefaultEditor = class(TDefaultEditor)
@@ -23,6 +12,11 @@ TncTCPSocketDefaultEditor = class(TDefaultEditor)
procedure EditProperty(const Prop: IProperty; var Continue: Boolean); override;
end;
+ TncUDPSocketDefaultEditor = class(TDefaultEditor) // Added UDP editor
+ public
+ procedure EditProperty(const Prop: IProperty; var Continue: Boolean); override;
+ end;
+
TncSourceDefaultEditor = class(TDefaultEditor)
public
procedure EditProperty(const Prop: IProperty; var Continue: Boolean); override;
@@ -34,10 +28,22 @@ implementation
procedure Register;
begin
- RegisterComponents('NetCom7', [TncTCPServer, TncTCPClient, TncServerSource, TncClientSource, TncCommandHandler, TncDBServer, TncDBDataset]);
+ RegisterComponents('NetCom7', [
+ TncTCPServer,
+ TncTCPClient,
+ TncUDPServer, // Added UDP components
+ TncUDPClient,
+ TncServerSource,
+ TncClientSource,
+ TncCommandHandler,
+ TncDBServer,
+ TncDBDataset
+ ]);
RegisterComponentEditor(TncTCPServer, TncTCPSocketDefaultEditor);
RegisterComponentEditor(TncTCPClient, TncTCPSocketDefaultEditor);
+ RegisterComponentEditor(TncUDPServer, TncUDPSocketDefaultEditor); // Added UDP editors
+ RegisterComponentEditor(TncUDPClient, TncUDPSocketDefaultEditor);
RegisterComponentEditor(TncServerSource, TncSourceDefaultEditor);
RegisterComponentEditor(TncClientSource, TncSourceDefaultEditor);
@@ -143,7 +149,20 @@ procedure TncTCPSocketDefaultEditor.EditProperty(const Prop: IProperty; var Cont
inherited;
end;
-{ TncCustomPeerSourceDefaultEditor }
+{ TncUDPSocketDefaultEditor } // Added UDP editor implementation
+
+procedure TncUDPSocketDefaultEditor.EditProperty(const Prop: IProperty; var Continue: Boolean);
+begin
+ if CompareText(Prop.GetName, 'ONREADDATAGRAM') = 0 then
+ begin
+ Prop.Edit;
+ Continue := False;
+ end
+ else
+ inherited;
+end;
+
+{ TncSourceDefaultEditor }
procedure TncSourceDefaultEditor.EditProperty(const Prop: IProperty; var Continue: Boolean);
begin
@@ -157,12 +176,10 @@ procedure TncSourceDefaultEditor.EditProperty(const Prop: IProperty; var Continu
end;
initialization
-
-RegisterSplashScreen;
-RegisterAboutBox;
+ RegisterSplashScreen;
+ RegisterAboutBox;
finalization
-
-UnregisterAboutBox;
+ UnregisterAboutBox;
end.
diff --git a/Source/ncIPUtils.pas b/Source/ncIPUtils.pas
new file mode 100644
index 0000000..08d3802
--- /dev/null
+++ b/Source/ncIPUtils.pas
@@ -0,0 +1,284 @@
+unit ncIPUtils;
+// /////////////////////////////////////////////////////////////////////////////
+//
+// NetCom7 Package - IP Address utils
+//
+//
+//
+// 21/01/2025
+// - Initial creation
+// Written by J.Pauwels
+//
+// /////////////////////////////////////////////////////////////////////////////
+
+interface
+
+uses
+ {$IFDEF MSWINDOWS}
+ Winapi.Windows, Winapi.Winsock2,
+ {$ELSE}
+ Posix.SysSocket, Posix.NetDB, Posix.NetIf, Posix.ArpaInet,
+ {$ENDIF}
+ System.SysUtils, System.Classes;
+
+const
+ IPV6_ADDR_LEN = 16; // IPv6 address length in bytes
+ IPV6_STR_MAX_LEN = 46; // Maximum string length for IPv6 address including null terminator
+ SOCKADDR_STORAGE_SIZE = 128; // Size of sockaddr_storage structure
+
+ {$IFDEF MSWINDOWS}
+ AF_INET6 = 23;
+ {$ENDIF}
+
+type
+ TIn6Addr = record
+ case Integer of
+ 0: (s6_bytes: array[0..15] of Byte);
+ 1: (s6_words: array[0..7] of Word);
+ end;
+ PIn6Addr = ^TIn6Addr;
+
+ TSockAddrIn6 = record
+ sin6_family: Word; // AF_INET6
+ sin6_port: Word; // Transport layer port #
+ sin6_flowinfo: Cardinal; // IPv6 flow information
+ sin6_addr: TIn6Addr; // IPv6 address
+ sin6_scope_id: Cardinal; // Set of interfaces for scope
+ end;
+ PSockAddrIn6 = ^TSockAddrIn6;
+
+ // Socket storage structure - used for both IPv4 and IPv6
+ TSockAddrStorage = record
+ ss_family: Word; // Address family
+ __ss_pad1: array [0..5] of Byte; // 6 bytes of padding
+ __ss_align: Int64; // Force alignment
+ __ss_pad2: array [0..111] of Byte; // 112 bytes of padding
+ end;
+ PSockAddrStorage = ^TSockAddrStorage;
+
+ EIPError = class(Exception);
+
+ // Function types for dynamic loading
+ {$IFDEF MSWINDOWS}
+ TInetPton = function(Family: Integer; const pszAddrString: PAnsiChar;
+ pAddrBuf: Pointer): Integer; stdcall;
+ TInetNtop = function(Family: Integer; pAddr: Pointer;
+ pStringBuf: PAnsiChar; StringBufSize: size_t): PAnsiChar; stdcall;
+ {$ENDIF}
+
+ TncIPUtils = class
+ private
+ {$IFDEF MSWINDOWS}
+ class var
+ InetPton: TInetPton;
+ InetNtop: TInetNtop;
+ class function LoadIPv6Functions: Boolean;
+ {$ENDIF}
+ public
+ class constructor Create;
+
+ // SockAddrStorage methods
+ class function StorageToString(const Storage: TSockAddrStorage): string;
+ class function IsIPv6Storage(const Storage: TSockAddrStorage): Boolean;
+ class function GetStorageFamily(const Storage: TSockAddrStorage): Word;
+ class function StorageToIPv6Address(const Storage: TSockAddrStorage;
+ out Addr: TSockAddrIn6): Boolean;
+ class function GetIPFromStorage(const Storage: TSockAddrStorage): string;
+ class function GetPortFromStorage(const Storage: TSockAddrStorage): Word;
+
+ // Existing IPv6 methods
+ class function IsIPv6ValidAddress(const AddrStr: string): Boolean;
+ class function AddressToString(const Addr: TIn6Addr): string;
+ class function StringToAddress(const AddrStr: string; out Addr: TIn6Addr): Boolean;
+ class function IsLinkLocal(const AddrStr: string): Boolean;
+ class function NormalizeAddress(const AddrStr: string): string;
+ class function AddressToPresentation(const Addr: TIn6Addr): string;
+ class function PresentationToAddress(const Present: string; var Addr: TIn6Addr): Boolean;
+ end;
+
+implementation
+
+{$IFDEF MSWINDOWS}
+var
+ Ws2_32DllHandle: THandle;
+
+
+class function TncIPUtils.LoadIPv6Functions: Boolean;
+begin
+ Result := False;
+
+ if Ws2_32DllHandle = 0 then
+ Ws2_32DllHandle := LoadLibrary('ws2_32.dll');
+
+ if Ws2_32DllHandle <> 0 then
+ begin
+ InetPton := GetProcAddress(Ws2_32DllHandle, 'inet_pton');
+ InetNtop := GetProcAddress(Ws2_32DllHandle, 'inet_ntop');
+ Result := Assigned(InetPton) and Assigned(InetNtop);
+ end;
+end;
+{$ENDIF}
+
+class constructor TncIPUtils.Create;
+begin
+ {$IFDEF MSWINDOWS}
+ if not LoadIPv6Functions then
+ raise EIPError.Create('Failed to load IPv6 functions from ws2_32.dll');
+ {$ENDIF}
+end;
+
+class function TncIPUtils.StorageToString(const Storage: TSockAddrStorage): string;
+begin
+ case Storage.ss_family of
+ AF_INET:
+ begin
+ var addr_in := PSockAddrIn(@Storage)^;
+ with addr_in.sin_addr.S_un_b do
+ Result := Format('%d.%d.%d.%d', [s_b1, s_b2, s_b3, s_b4]);
+ end;
+
+ AF_INET6:
+ begin
+ var addr_in6 := PSockAddrIn6(@Storage)^;
+ Result := AddressToString(addr_in6.sin6_addr);
+ if IsLinkLocal(Result) then
+ Result := Format('%s%%%d', [Result, addr_in6.sin6_scope_id]);
+ end;
+ else
+ Result := '';
+ end;
+end;
+
+class function TncIPUtils.IsIPv6Storage(const Storage: TSockAddrStorage): Boolean;
+begin
+ Result := Storage.ss_family = AF_INET6;
+end;
+
+class function TncIPUtils.GetStorageFamily(const Storage: TSockAddrStorage): Word;
+begin
+ Result := Storage.ss_family;
+end;
+
+class function TncIPUtils.StorageToIPv6Address(const Storage: TSockAddrStorage;
+ out Addr: TSockAddrIn6): Boolean;
+begin
+ Result := Storage.ss_family = AF_INET6;
+ if Result then
+ Addr := PSockAddrIn6(@Storage)^;
+end;
+
+class function TncIPUtils.GetIPFromStorage(const Storage: TSockAddrStorage): string;
+begin
+ Result := StorageToString(Storage);
+end;
+
+class function TncIPUtils.GetPortFromStorage(const Storage: TSockAddrStorage): Word;
+begin
+ case Storage.ss_family of
+ AF_INET: Result := ntohs(PSockAddrIn(@Storage)^.sin_port);
+ AF_INET6: Result := ntohs(PSockAddrIn6(@Storage)^.sin6_port);
+ else
+ Result := 0;
+ end;
+end;
+
+class function TncIPUtils.IsIPv6ValidAddress(const AddrStr: string): Boolean;
+var
+ Addr: TIn6Addr;
+begin
+ Result := StringToAddress(AddrStr, Addr);
+end;
+
+class function TncIPUtils.AddressToString(const Addr: TIn6Addr): string;
+var
+ StringBuffer: array[0..IPV6_STR_MAX_LEN-1] of AnsiChar;
+begin
+ {$IFDEF MSWINDOWS}
+ if InetNtop(AF_INET6, @Addr, StringBuffer, IPV6_STR_MAX_LEN) = nil then
+ raise EIPError.Create('Failed to convert IPv6 address to string: ' +
+ SysErrorMessage(WSAGetLastError));
+ {$ELSE}
+ if Posix.ArpaInet.inet_ntop(AF_INET6, @Addr, StringBuffer, IPV6_STR_MAX_LEN) = nil then
+ raise EIPv6Error.Create('Failed to convert IPv6 address to string: ' +
+ SysErrorMessage(GetLastError));
+ {$ENDIF}
+
+ Result := string(AnsiString(StringBuffer));
+end;
+
+class function TncIPUtils.StringToAddress(const AddrStr: string; out Addr: TIn6Addr): Boolean;
+var
+ AnsiAddr: AnsiString;
+begin
+ AnsiAddr := AnsiString(AddrStr);
+ {$IFDEF MSWINDOWS}
+ Result := InetPton(AF_INET6, PAnsiChar(AnsiAddr), @Addr) = 1;
+ {$ELSE}
+ Result := Posix.ArpaInet.inet_pton(AF_INET6, PAnsiChar(AnsiAddr), @Addr) = 1;
+ {$ENDIF}
+end;
+
+class function TncIPUtils.IsLinkLocal(const AddrStr: string): Boolean;
+begin
+ // Link-local addresses start with fe80::/10
+ Result := (Length(AddrStr) >= 4) and
+ (LowerCase(Copy(AddrStr, 1, 4)) = 'fe80');
+end;
+
+class function TncIPUtils.NormalizeAddress(const AddrStr: string): string;
+var
+ Addr: TIn6Addr;
+begin
+ if StringToAddress(AddrStr, Addr) then
+ Result := AddressToString(Addr)
+ else
+ raise EIPError.CreateFmt('Invalid IPv6 address: %s', [AddrStr]);
+end;
+
+class function TncIPUtils.AddressToPresentation(const Addr: TIn6Addr): string;
+var
+ i: Integer;
+ NonZeroFound: Boolean;
+begin
+ Result := '';
+ NonZeroFound := False;
+
+ // Convert words to hex representation
+ for i := 0 to 7 do
+ begin
+ if (Addr.s6_words[i] <> 0) or NonZeroFound then
+ begin
+ if Result <> '' then
+ Result := Result + ':';
+ Result := Result + IntToHex(Addr.s6_words[i], 1);
+ NonZeroFound := True;
+ end;
+ end;
+
+ // Handle all-zero case
+ if Result = '' then
+ Result := '::'
+ else if not NonZeroFound then
+ Result := Result + ':';
+end;
+
+class function TncIPUtils.PresentationToAddress(const Present: string;
+ var Addr: TIn6Addr): Boolean;
+begin
+ FillChar(Addr, SizeOf(Addr), 0);
+ Result := StringToAddress(Present, Addr);
+end;
+
+initialization
+ {$IFDEF MSWINDOWS}
+ Ws2_32DllHandle := 0;
+ {$ENDIF}
+
+finalization
+ {$IFDEF MSWINDOWS}
+ if Ws2_32DllHandle <> 0 then
+ FreeLibrary(Ws2_32DllHandle);
+ {$ENDIF}
+
+end.
+
diff --git a/Source/ncLines.pas b/Source/ncLines.pas
index d6bf8d7..713c1e6 100644
--- a/Source/ncLines.pas
+++ b/Source/ncLines.pas
@@ -6,6 +6,11 @@
// socket, organised in an object which contains the handle of the socket,
// and also makes sure it checks every API command for errors
//
+// 14/01/2025 - by J.Pauwels
+// - Fix Linux compilation
+// - Added UDP support
+// - Added IPV6 support
+//
// 9/8/2020
// - Completed multiplatform support, now NetCom can be compiled in all
// platforms
@@ -39,11 +44,19 @@ interface
System.Math,
System.SysUtils,
System.Diagnostics,
+ System.IOUtils,
+ System.Classes,
+ ncIPUtils,
ncThreads;
const
// Flag that indicates that the socket is intended for bind() + listen() when constructing it
AI_PASSIVE = 1;
+ IPV6_V6ONLY = 27;
+ AI_ADDRCONFIG = $0020; // Return only if local system configured
+ AI_NUMERICHOST = $0004; // Don't use name resolution
+ INET6_ADDRSTRLEN = 46;
+ // Maximum length of IPv6 address string including null terminator
{$IFDEF MSWINDOWS}
InvalidSocket = Winapi.Winsock2.INVALID_SOCKET;
SocketError = SOCKET_ERROR;
@@ -54,6 +67,25 @@ interface
TCP_NODELAY = $0001;
{$ENDIF}
+type
+ TSocketType = (stUDP, stTCP);
+
+const
+ CSocketTypeNames: array [TSocketType] of string = ('UDP', 'TCP');
+
+ CRawSocketTypes: array [TSocketType] of Integer = (SOCK_DGRAM, // UDP datagram
+ SOCK_STREAM // TCP stream
+ );
+
+ CRawProtocolTypes: array [TSocketType] of Integer = (IPPROTO_UDP,
+ IPPROTO_TCP);
+
+type
+ TAddressType = (afIPv4, afIPv6);
+
+const
+ CAddressTypeNames: array [TAddressType] of string = ('IPv4', 'IPv6');
+
type
{$IFDEF MSWINDOWS}
TSocketHandle = Winapi.Winsock2.TSocket;
@@ -72,7 +104,8 @@ TAddrInfoW = record
ai_next: PAddrInfoW;
end;
- TGetAddrInfoW = function(NodeName: PWideChar; ServiceName: PWideChar; Hints: PAddrInfoW; ppResult: PPAddrInfoW): Integer; stdcall;
+ TGetAddrInfoW = function(NodeName: PWideChar; ServiceName: PWideChar;
+ Hints: PAddrInfoW; ppResult: PPAddrInfoW): Integer; stdcall;
TFreeAddrInfoW = procedure(ai: PAddrInfoW); stdcall;
{$ELSE}
TSocketHandle = Integer;
@@ -91,6 +124,7 @@ TConnectThread = class(TncReadyThread)
ConnectResult: Integer;
procedure ProcessEvent; override;
end;
+
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TncLine
// Bring in all functionality from WinSock API, with appropriate exception raising on errors
@@ -99,6 +133,9 @@ TncLine = class(TObject)
private const
DefaultConnectTimeout = 100; // msec
private
+ FKind: TSocketType;
+ FFamily: TAddressType;
+ FMaxPort: Integer;
FActive: Boolean;
FLastSent: Int64;
FLastReceived: Int64;
@@ -110,11 +147,13 @@ TncLine = class(TObject)
PropertyLock: TCriticalSection;
FHandle: TSocketHandle;
FConnectTimeout: Integer;
+
{$IFDEF MSWINDOWS}
AddrResult: PAddrInfoW;
{$ELSE}
AddrResult: Paddrinfo;
{$ENDIF}
+ function IsConnectionBased: Boolean;
procedure SetConnected;
procedure SetDisconnected;
function GetReceiveTimeout: Integer;
@@ -125,12 +164,20 @@ TncLine = class(TObject)
procedure SetLastReceived(const Value: Int64);
function GetLastSent: Int64;
procedure SetLastSent(const Value: Int64);
+ protected const
+ DefaultKind = stTCP;
+
+ const
+ DefaultFamily = afIPv4;
protected
+ procedure SetKind(const AKind: TSocketType);
+ procedure SetFamily(const Value: TAddressType);
function CreateLineObject: TncLine; virtual;
procedure Check(aCmdRes: Integer); inline;
// API functions
- procedure CreateClientHandle(const aHost: string; const aPort: Integer);
+ procedure CreateClientHandle(const aHost: string; const aPort: Integer;
+ const aBroadcast: Boolean = False);
procedure CreateServerHandle(const aPort: Integer);
procedure DestroyHandle;
@@ -141,35 +188,47 @@ TncLine = class(TObject)
procedure EnableNoDelay; inline;
procedure EnableKeepAlive; inline;
+ procedure EnableBroadcast; inline;
+ procedure EnableIPv6Only; inline;
+
procedure EnableReuseAddress; inline;
procedure SetReceiveSize(const aBufferSize: Integer);
procedure SetWriteSize(const aBufferSize: Integer);
- property OnConnected: TncLineOnConnectDisconnect read FOnConnected write FOnConnected;
- property OnDisconnected: TncLineOnConnectDisconnect read FOnDisconnected write FOnDisconnected;
+ property OnConnected: TncLineOnConnectDisconnect read FOnConnected
+ write FOnConnected;
+ property OnDisconnected: TncLineOnConnectDisconnect read FOnDisconnected
+ write FOnDisconnected;
public
constructor Create; overload; virtual;
destructor Destroy; override;
+ property Kind: TSocketType read FKind;
+ property Family: TAddressType read FFamily;
property Handle: TSocketHandle read FHandle;
property Active: Boolean read FActive;
property LastSent: Int64 read GetLastSent write SetLastSent;
property LastReceived: Int64 read GetLastReceived write SetLastReceived;
property PeerIP: string read FPeerIP;
property DataObject: TObject read FDataObject write FDataObject;
- property ConnectTimeout: Integer read FConnectTimeout write FConnectTimeout default DefaultConnectTimeout;
- property ReceiveTimeout: Integer read GetReceiveTimeout write SetReceiveTimeout;
+ property ConnectTimeout: Integer read FConnectTimeout write FConnectTimeout
+ default DefaultConnectTimeout;
+ property ReceiveTimeout: Integer read GetReceiveTimeout
+ write SetReceiveTimeout;
property SendTimeout: Integer read GetSendTimeout write SetSendTimeout;
end;
-function Readable(const aSocketHandleArray: TSocketHandleArray; const aTimeout: Cardinal): TSocketHandleArray;
-function ReadableAnySocket(const aSocketHandleArray: TSocketHandleArray; const aTimeout: Cardinal): Boolean; inline;
+function Readable(const aSocketHandleArray: TSocketHandleArray;
+ const aTimeout: Cardinal): TSocketHandleArray;
+function ReadableAnySocket(const aSocketHandleArray: TSocketHandleArray;
+ const aTimeout: Cardinal): Boolean; inline;
implementation
// Readable checks to see if any socket handles have data
// and if so, overwrites aReadFDS with the data
-function Readable(const aSocketHandleArray: TSocketHandleArray; const aTimeout: Cardinal): TSocketHandleArray;
+function Readable(const aSocketHandleArray: TSocketHandleArray;
+ const aTimeout: Cardinal): TSocketHandleArray;
{$IFDEF MSWINDOWS}
var
TimeoutValue: timeval;
@@ -193,7 +252,8 @@ function Readable(const aSocketHandleArray: TSocketHandleArray; const aTimeout:
if FDSetPtr^.fd_count > 0 then
begin
SetLength(Result, FDSetPtr^.fd_count);
- move(FDSetPtr^.fd_array[0], Result[0], FDSetPtr^.fd_count * SizeOf(TSocketHandle));
+ move(FDSetPtr^.fd_array[0], Result[0], FDSetPtr^.fd_count *
+ SizeOf(TSocketHandle));
end
else
SetLength(Result, 0); // This is needed with newer compilers
@@ -201,6 +261,7 @@ function Readable(const aSocketHandleArray: TSocketHandleArray; const aTimeout:
FreeMem(FDSetPtr);
end;
end;
+
{$ELSE}
var
@@ -228,10 +289,12 @@ function Readable(const aSocketHandleArray: TSocketHandleArray; const aTimeout:
begin
SocketHandle := aSocketHandleArray[i];
FDNdx := SocketHandle div NFDBITS;
- FDSetPtr.fds_bits[FDNdx] := FDSetPtr.fds_bits[FDNdx] or (1 shl (SocketHandle mod NFDBITS));
+ FDSetPtr.fds_bits[FDNdx] := FDSetPtr.fds_bits[FDNdx] or
+ (1 shl (SocketHandle mod NFDBITS));
end;
- ReadySockets := Select(FDArrayLen * NFDBITS, FDSetPtr, nil, nil, @TimeoutValue);
+ ReadySockets := Select(FDArrayLen * NFDBITS, FDSetPtr, nil, nil,
+ @TimeoutValue);
if ReadySockets > 0 then
begin
@@ -242,7 +305,8 @@ function Readable(const aSocketHandleArray: TSocketHandleArray; const aTimeout:
begin
SocketHandle := aSocketHandleArray[i];
FDNdx := SocketHandle div NFDBITS;
- if FDSetPtr.fds_bits[FDNdx] and (1 shl (SocketHandle mod NFDBITS)) <> 0 then
+ if FDSetPtr.fds_bits[FDNdx] and (1 shl (SocketHandle mod NFDBITS)) <> 0
+ then
begin
Result[ResultNdx] := SocketHandle;
ResultNdx := ResultNdx + 1;
@@ -257,7 +321,8 @@ function Readable(const aSocketHandleArray: TSocketHandleArray; const aTimeout:
end;
{$ENDIF}
-function ReadableAnySocket(const aSocketHandleArray: TSocketHandleArray; const aTimeout: Cardinal): Boolean;
+function ReadableAnySocket(const aSocketHandleArray: TSocketHandleArray;
+ const aTimeout: Cardinal): Boolean;
begin
Result := Length(Readable(aSocketHandleArray, aTimeout)) > 0;
end;
@@ -268,7 +333,8 @@ function ReadableAnySocket(const aSocketHandleArray: TSocketHandleArray; const a
DllGetAddrInfo: TGetAddrInfoW = nil;
DllFreeAddrInfo: TFreeAddrInfoW = nil;
-procedure GetAddressInfo(NodeName: PWideChar; ServiceName: PWideChar; Hints: PAddrInfoW; ppResult: PPAddrInfoW);
+procedure GetAddressInfo(NodeName: PWideChar; ServiceName: PWideChar;
+ Hints: PAddrInfoW; ppResult: PPAddrInfoW);
var
iRes: Integer;
begin
@@ -285,6 +351,31 @@ procedure FreeAddressInfo(ai: PAddrInfoW);
DllFreeAddrInfo(ai);
end;
+function IsBroadcastAddress(const aHost: string): Boolean;
+var
+ Octets: TArray;
+ LastOctet: Integer;
+begin
+ // Split the IP into octets
+ Octets := aHost.Split(['.']);
+
+ // Basic validation
+ if Length(Octets) <> 4 then
+ Exit(False);
+
+ // Try to parse last octet
+ if not TryStrToInt(Octets[3], LastOctet) then
+ Exit(False);
+
+ Result :=
+ // Global broadcast
+ (aHost = '255.255.255.255') or
+ // Limited broadcast
+ (aHost = '0.0.0.0') or
+ // Subnet broadcast (last octet is 255)
+ (LastOctet = 255);
+end;
+
{$ENDIF}
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{ TncLine }
@@ -295,8 +386,9 @@ constructor TncLine.Create;
inherited Create;
PropertyLock := TCriticalSection.Create;
-
FHandle := InvalidSocket;
+ FKind := DefaultKind;
+ FFamily := DefaultFamily;
FConnectTimeout := DefaultConnectTimeout;
FActive := False;
@@ -315,13 +407,14 @@ destructor TncLine.Destroy;
DestroyHandle;
PropertyLock.Free;
-
inherited Destroy;
end;
function TncLine.CreateLineObject: TncLine;
begin
Result := TncLine.Create;
+ Result.SetKind(Kind);
+ Result.SetFamily(Family);
end;
/// /////////////////////////////////////////////////////////////////////////////
@@ -336,53 +429,104 @@ procedure TncLine.Check(aCmdRes: Integer);
{$ENDIF}
end;
-procedure TncLine.CreateClientHandle(const aHost: string; const aPort: Integer);
+procedure TncLine.CreateClientHandle(const aHost: string; const aPort: Integer;
+ const aBroadcast: Boolean = False);
var
ConnectThread: TConnectThread;
{$IFDEF MSWINDOWS}
Hints: TAddrInfoW;
+ ErrorCode: Integer;
{$ELSE}
Hints: addrinfo;
AnsiHost, AnsiPort: RawByteString;
{$ENDIF}
+ ResolveHost: string;
begin
try
+ // Validate host for IPv6 if applicable
+ if (FFamily = afIPv6) and (aHost <> '') and (LowerCase(aHost) <> 'localhost') then
+ begin
+ // Validate IPv6 address format if it looks like an IPv6 address
+ if (Pos(':', aHost) > 0) and not TncIPUtils.IsIPv6ValidAddress(aHost) then
+ raise EIPError.CreateFmt('Invalid IPv6 address format: %s', [aHost]);
+ end;
+
+ if IsBroadcastAddress(aHost) and not aBroadcast then
+ raise Exception.Create('Cannot use broadcast address when Broadcast is False');
+
FillChar(Hints, SizeOf(Hints), 0);
- Hints.ai_family := AF_INET;
- Hints.ai_socktype := SOCK_STREAM;
- Hints.ai_protocol := IPPROTO_TCP;
+
+ // Set address family and related flags based on FFamily
+ case FFamily of
+ afIPv4:
+ begin
+ Hints.ai_family := AF_INET;
+ if LowerCase(aHost) = 'localhost' then
+ ResolveHost := '127.0.0.1'
+ else
+ ResolveHost := aHost;
+ end;
+ afIPv6:
+ begin
+ Hints.ai_family := AF_INET6;
+ Hints.ai_flags := AI_ADDRCONFIG;
+ // If it's a valid IPv6 address, normalize it
+ if (Pos(':', aHost) > 0) and TncIPUtils.IsIPv6ValidAddress(aHost) then
+ ResolveHost := TncIPUtils.NormalizeAddress(aHost)
+ else
+ ResolveHost := aHost;
+
+ // Handle link-local addresses correctly
+ if TncIPUtils.IsLinkLocal(ResolveHost) then
+ begin
+ // Extract scope ID if present in the address
+ var ScopePos := Pos('%', ResolveHost);
+ if ScopePos > 0 then
+ ResolveHost := Copy(ResolveHost, 1, ScopePos - 1);
+ end;
+ end;
+ end;
+
+ Hints.ai_socktype := CRawSocketTypes[FKind];
+ Hints.ai_protocol := CRawProtocolTypes[FKind];
+
+ // Create the socket first
+ FHandle := Socket(Hints.ai_family, CRawSocketTypes[FKind],
+ CRawProtocolTypes[FKind]);
+ if FHandle = InvalidSocket then
+ begin
+ ErrorCode :=
+{$IFDEF MSWINDOWS}WSAGetLastError(){$ELSE}GetLastError(){$ENDIF};
+ raise Exception.Create(Format('Socket creation failed: %s',
+ [SysErrorMessage(ErrorCode)]));
+ end;
// Resolve the server address and port
{$IFDEF MSWINDOWS}
- GetAddressInfo(PChar(aHost), PChar(IntToStr(aPort)), @Hints, @AddrResult);
+ GetAddressInfo(PChar(ResolveHost), PChar(IntToStr(aPort)), @Hints,
+ @AddrResult);
{$ELSE}
- AnsiHost := RawByteString(aHost);
+ AnsiHost := RawByteString(ResolveHost);
AnsiPort := RawByteString(IntToStr(aPort));
-
- GetAddrInfo(MarshaledAString(AnsiHost), MarshaledAString(AnsiPort), Hints, AddrResult);
+ GetAddrInfo(MarshaledAString(AnsiHost), MarshaledAString(AnsiPort), Hints,
+ AddrResult);
{$ENDIF}
try
- // Create a SOCKET for connecting to server
- FHandle := Socket(AddrResult^.ai_family, AddrResult^.ai_socktype, AddrResult^.ai_protocol);
- Check(FHandle);
- try
{$IFNDEF MSWINDOWS}
- EnableReuseAddress;
+ EnableReuseAddress;
{$ENDIF}
+ if IsConnectionBased then
+ begin
ConnectThread := TConnectThread.Create;
try
ConnectThread.Line := Self;
ConnectThread.ConnectResult := -1;
-
- // Connect to server
ConnectThread.ReadyEvent.WaitFor;
ConnectThread.ReadyEvent.ResetEvent;
ConnectThread.WakeupEvent.SetEvent;
ConnectThread.WaitForReady(FConnectTimeout);
-
if ConnectThread.ConnectResult = -1 then
raise EncLineException.Create('Connect timeout');
-
Check(ConnectThread.ConnectResult);
SetConnected;
finally
@@ -390,20 +534,43 @@ procedure TncLine.CreateClientHandle(const aHost: string; const aPort: Integer);
ConnectThread.Terminate;
ConnectThread.WakeupEvent.SetEvent;
end;
- except
- DestroyHandle;
- raise;
+ end
+ else
+ begin
+ // For UDP, handle IPv4 and IPv6 differently
+ case FFamily of
+ afIPv4:
+ begin
+ // IPv4 UDP needs connect
+ if not aBroadcast then
+ Check(Connect(FHandle, AddrResult^.ai_addr^,
+ AddrResult^.ai_addrlen));
+ SetConnected;
+ end;
+ afIPv6:
+ begin
+ // For IPv6 UDP with link-local addresses, ensure scope ID is set
+ if TncIPUtils.IsLinkLocal(ResolveHost) then
+ begin
+ var AddrIn6 := PSockAddrIn6(AddrResult^.ai_addr)^;
+ // Set appropriate scope ID if needed
+ // Add a method to get interface index ?
+ end;
+ SetConnected;
+ end;
+ end;
end;
- finally
+
+ except
+ DestroyHandle;
+ raise;
+ end;
+ finally
{$IFDEF MSWINDOWS}
- FreeAddressInfo(AddrResult);
+ FreeAddressInfo(AddrResult);
{$ELSE}
- freeaddrinfo(AddrResult^);
+ freeaddrinfo(AddrResult^);
{$ENDIF}
- end;
- except
- FHandle := InvalidSocket;
- raise;
end;
end;
@@ -417,9 +584,18 @@ procedure TncLine.CreateServerHandle(const aPort: Integer);
{$ENDIF}
begin
FillChar(Hints, SizeOf(Hints), 0);
- Hints.ai_family := AF_INET;
- Hints.ai_socktype := SOCK_STREAM;
- Hints.ai_protocol := IPPROTO_TCP;
+ case FFamily of
+ afIPv4:
+ begin
+ Hints.ai_family := AF_INET;
+ end;
+ afIPv6:
+ begin
+ Hints.ai_family := AF_INET6;
+ end;
+ end;
+ Hints.ai_socktype := CRawSocketTypes[FKind];
+ Hints.ai_protocol := CRawProtocolTypes[FKind];
Hints.ai_flags := AI_PASSIVE; // Inform GetAddrInfo to return a server socket
// Resolve the server address and port
@@ -431,15 +607,22 @@ procedure TncLine.CreateServerHandle(const aPort: Integer);
{$ENDIF}
try
// Create a server listener socket
- FHandle := Socket(AddrResult^.ai_family, AddrResult^.ai_socktype, AddrResult^.ai_protocol);
+ FHandle := Socket(AddrResult^.ai_family, AddrResult^.ai_socktype,
+ AddrResult^.ai_protocol);
Check(FHandle);
try
+ EnableIPv6Only;
+
{$IFNDEF MSWINDOWS}
EnableReuseAddress;
{$ENDIF}
- // Setup the TCP listening socket
- Check(Bind(FHandle, AddrResult^.ai_addr^, AddrResult^.ai_addrlen));
- Check(Listen(FHandle, SOMAXCONN));
+ // Bind the socket
+ Check(bind(FHandle, AddrResult^.ai_addr^, AddrResult^.ai_addrlen));
+
+ // For TCP, we need to listen for incoming connections
+ if IsConnectionBased then
+ Check(Listen(FHandle, SOMAXCONN));
+
SetConnected;
except
DestroyHandle;
@@ -467,12 +650,15 @@ procedure TncLine.DestroyHandle;
Posix.Unistd.__Close(FHandle);
{$ENDIF}
except
+ on E: Exception do
+ //
end;
try
SetDisconnected;
except
+ on E: Exception do
+ //
end;
-
FHandle := InvalidSocket;
end;
end;
@@ -481,14 +667,14 @@ function TncLine.AcceptLine: TncLine;
var
NewHandle: TSocketHandle;
{$IFNDEF MSWINDOWS}
- Addr: sockaddr;
+ addr: sockaddr;
AddrLen: socklen_t;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
NewHandle := Accept(FHandle, nil, nil);
{$ELSE}
- NewHandle := Accept(FHandle, Addr, AddrLen);
+ NewHandle := Accept(FHandle, addr, AddrLen);
{$ENDIF}
if NewHandle = InvalidSocket then
Abort; // raise silent exception
@@ -503,31 +689,43 @@ function TncLine.AcceptLine: TncLine;
function TncLine.SendBuffer(const aBuf; aLen: Integer): Integer;
begin
- // Send all buffer in one go, the most optimal by far
Result := Send(FHandle, aBuf, aLen, 0);
- try
- if Result = SocketError then
- Abort; // raise silent exception instead of Check
+ if Result = SocketError then
+ begin
+ if IsConnectionBased then
+ try
+ Abort; // TCP: raise silent exception
+ except
+ DestroyHandle;
+ raise;
+ end
+ else
+ Check(Result); // UDP: normal error check
+ end
+ else
LastSent := TStopWatch.GetTimeStamp;
- except
- DestroyHandle;
- raise;
- end;
end;
function TncLine.RecvBuffer(var aBuf; aLen: Integer): Integer;
begin
Result := recv(FHandle, aBuf, aLen, 0);
- try
- if (Result = SocketError) or (Result = 0) then
- Abort; // raise silent exception instead of Check, something has disconnected
+ if (Result = SocketError) or
+ (IsConnectionBased and (Result = 0)) then // TCP: 0 means disconnected
+ begin
+ if IsConnectionBased then
+ try
+ Abort; // TCP: raise silent exception
+ except
+ DestroyHandle;
+ raise;
+ end
+ else
+ Check(Result); // UDP: normal error check
+ end
+ else
LastReceived := TStopWatch.GetTimeStamp;
- except
- DestroyHandle;
- raise;
- end;
end;
procedure TncLine.EnableNoDelay;
@@ -536,7 +734,8 @@ procedure TncLine.EnableNoDelay;
begin
optval := 1;
{$IFDEF MSWINDOWS}
- Check(SetSockOpt(FHandle, IPPROTO_TCP, TCP_NODELAY, PAnsiChar(@optval), SizeOf(optval)));
+ Check(SetSockOpt(FHandle, IPPROTO_TCP, TCP_NODELAY, PAnsiChar(@optval),
+ SizeOf(optval)));
{$ELSE}
Check(SetSockOpt(FHandle, IPPROTO_TCP, TCP_NODELAY, optval, SizeOf(optval)));
{$ENDIF}
@@ -548,73 +747,150 @@ procedure TncLine.EnableKeepAlive;
begin
optval := 1; // any non zero indicates true
{$IFDEF MSWINDOWS}
- Check(SetSockOpt(FHandle, SOL_SOCKET, SO_KEEPALIVE, PAnsiChar(@optval), SizeOf(optval)));
+ Check(SetSockOpt(FHandle, SOL_SOCKET, SO_KEEPALIVE, PAnsiChar(@optval),
+ SizeOf(optval)));
{$ELSE}
Check(SetSockOpt(FHandle, SOL_SOCKET, SO_KEEPALIVE, optval, SizeOf(optval)));
{$ENDIF}
end;
+procedure TncLine.EnableBroadcast;
+var
+ optval: Integer;
+begin
+ optval := 1;
+{$IFDEF MSWINDOWS}
+ Check(SetSockOpt(FHandle, SOL_SOCKET, SO_BROADCAST, PAnsiChar(@optval),
+ SizeOf(optval)));
+{$ELSE}
+ Check(SetSockOpt(FHandle, SOL_SOCKET, SO_BROADCAST, optval, SizeOf(optval)));
+{$ENDIF}
+end;
+
+procedure TncLine.EnableIPv6Only;
+var
+ optval: Integer;
+begin
+ if FFamily = afIPv6 then
+ begin
+ optval := 1;
+{$IFDEF MSWINDOWS}
+ Check(SetSockOpt(FHandle, IPPROTO_IPV6, IPV6_V6ONLY, PAnsiChar(@optval),
+ SizeOf(optval)));
+{$ELSE}
+ Check(SetSockOpt(FHandle, IPPROTO_IPV6, IPV6_V6ONLY, optval,
+ SizeOf(optval)));
+{$ENDIF}
+ end;
+end;
+
procedure TncLine.EnableReuseAddress;
var
optval: Integer;
begin
optval := 1;
{$IFDEF MSWINDOWS}
- Check(SetSockOpt(FHandle, SOL_SOCKET, SO_REUSEADDR, PAnsiChar(@optval), SizeOf(optval)));
+ Check(SetSockOpt(FHandle, SOL_SOCKET, SO_REUSEADDR, PAnsiChar(@optval),
+ SizeOf(optval)));
{$ELSE}
Check(SetSockOpt(FHandle, SOL_SOCKET, SO_REUSEADDR, optval, SizeOf(optval)));
{$ENDIF}
end;
+procedure TncLine.SetKind(const AKind: TSocketType);
+begin
+ if FHandle = InvalidSocket then // TODO: Raise exception otherwise???
+ begin
+ FKind := AKind;
+ end;
+end;
+
+procedure TncLine.SetFamily(const Value: TAddressType);
+begin
+ if FHandle = InvalidSocket then
+ // Only allow changing family when socket is not active
+ begin
+ FFamily := Value;
+ end
+ else
+ // Form1.Log('WARNING: Attempted to change Family while socket is active');
+end;
+
+function TncLine.IsConnectionBased: Boolean;
+begin
+ Result := FKind = stTCP;
+end;
+
procedure TncLine.SetReceiveSize(const aBufferSize: Integer);
begin
// min is 512 bytes, max is 1048576
{$IFDEF MSWINDOWS}
- Check(SetSockOpt(FHandle, SOL_SOCKET, SO_RCVBUF, PAnsiChar(@aBufferSize), SizeOf(aBufferSize)));
+ Check(SetSockOpt(FHandle, SOL_SOCKET, SO_RCVBUF, PAnsiChar(@aBufferSize),
+ SizeOf(aBufferSize)));
{$ELSE}
- Check(SetSockOpt(FHandle, SOL_SOCKET, SO_RCVBUF, aBufferSize, SizeOf(aBufferSize)));
+ Check(SetSockOpt(FHandle, SOL_SOCKET, SO_RCVBUF, aBufferSize,
+ SizeOf(aBufferSize)));
{$ENDIF}
end;
procedure TncLine.SetWriteSize(const aBufferSize: Integer);
begin
{$IFDEF MSWINDOWS}
- Check(SetSockOpt(FHandle, SOL_SOCKET, SO_SNDBUF, PAnsiChar(@aBufferSize), SizeOf(aBufferSize)));
+ Check(SetSockOpt(FHandle, SOL_SOCKET, SO_SNDBUF, PAnsiChar(@aBufferSize),
+ SizeOf(aBufferSize)));
{$ELSE}
- Check(SetSockOpt(FHandle, SOL_SOCKET, SO_RCVBUF, aBufferSize, SizeOf(aBufferSize)));
+ Check(SetSockOpt(FHandle, SOL_SOCKET, SO_RCVBUF, aBufferSize,
+ SizeOf(aBufferSize)));
{$ENDIF}
end;
procedure TncLine.SetConnected;
var
- Addr: sockaddr;
-{$IFDEF MSWINDOWS}
- AddrSize: Integer;
-{$ELSE}
- AddrSize: socklen_t;
-{$ENDIF}
+ addr: TSockAddrStorage;
+ AddrSize: {$IFDEF MSWINDOWS}Integer{$ELSE}socklen_t{$ENDIF};
begin
if not FActive then
begin
FActive := True;
-
LastSent := TStopWatch.GetTimeStamp;
LastReceived := LastSent;
- AddrSize := SizeOf(Addr);
- if GetPeerName(FHandle, Addr, AddrSize) <> SocketError then
+ if IsConnectionBased then
begin
- // FPeerIP := IntToStr(Ord(addr.sin_addr.S_un_b.s_b1)) + '.' + IntToStr(Ord(addr.sin_addr.S_un_b.s_b2)) + '.' + IntToStr(Ord(addr.sin_addr.S_un_b.s_b3)) +
- // '.' + IntToStr(Ord(addr.sin_addr.S_un_b.s_b4));
- FPeerIP :=
+ // Get peer information
+ AddrSize := SizeOf(TSockAddrStorage);
- IntToStr(Ord(Addr.sa_data[2])) + '.' +
-
- IntToStr(Ord(Addr.sa_data[3])) + '.' +
-
- IntToStr(Ord(Addr.sa_data[4])) + '.' +
+ if GetPeerName(FHandle, PSOCKADDR(@addr)^, AddrSize) = 0 then
+ begin
+ try
+ FPeerIP := TncIPUtils.GetIPFromStorage(addr);
+ except
+ on E: EIPError do
+ FPeerIP := '';
+ end;
- IntToStr(Ord(Addr.sa_data[5]));
+ // If we got an empty string, set default values based on family
+ if FPeerIP = '' then
+ begin
+ case FFamily of
+ afIPv4: FPeerIP := '0.0.0.0';
+ afIPv6: FPeerIP := '::';
+ end;
+ end;
+ end
+ else
+ begin
+ var ErrorCode := {$IFDEF MSWINDOWS}WSAGetLastError(){$ELSE}GetLastError(){$ENDIF};
+ FPeerIP := '';
+ end;
+ end
+ else
+ begin
+ // For UDP, we're always "connected" but might not have peer info yet
+ case FFamily of
+ afIPv4: FPeerIP := '0.0.0.0';
+ afIPv6: FPeerIP := '::';
+ end;
end;
if Assigned(OnConnected) then
@@ -641,8 +917,8 @@ procedure TncLine.SetDisconnected;
function TncLine.GetReceiveTimeout: Integer;
var
- Opt: DWord;
- OptSize: Integer;
+ Opt: Cardinal;
+ OptSize: {$IFDEF MSWINDOWS}Integer{$ELSE}socklen_t{$ENDIF};
begin
OptSize := SizeOf(Opt);
{$IFDEF MSWINDOWS}
@@ -655,7 +931,7 @@ function TncLine.GetReceiveTimeout: Integer;
procedure TncLine.SetReceiveTimeout(const Value: Integer);
var
- Opt: DWord;
+ Opt: Cardinal;
OptSize: Integer;
begin
Opt := Value;
@@ -669,8 +945,8 @@ procedure TncLine.SetReceiveTimeout(const Value: Integer);
function TncLine.GetSendTimeout: Integer;
var
- Opt: DWord;
- OptSize: Integer;
+ Opt: Cardinal;
+ OptSize: {$IFDEF MSWINDOWS}Integer{$ELSE}socklen_t{$ENDIF};
begin
OptSize := SizeOf(Opt);
{$IFDEF MSWINDOWS}
@@ -683,7 +959,7 @@ function TncLine.GetSendTimeout: Integer;
procedure TncLine.SetSendTimeout(const Value: Integer);
var
- Opt: DWord;
+ Opt: Cardinal;
OptSize: Integer;
begin
Opt := Value;
@@ -737,11 +1013,11 @@ procedure TncLine.SetLastSent(const Value: Int64);
{$IFDEF MSWINDOWS}
+// Windows-specific types and variables
var
ExtDllHandle: THandle = 0;
procedure AttachAddrInfo;
-
procedure SafeLoadFrom(aDll: string);
begin
if not Assigned(DllGetAddrInfo) then
@@ -761,33 +1037,41 @@ procedure AttachAddrInfo;
end;
begin
- SafeLoadFrom('ws2_32.dll'); // WinSock2 dll
- SafeLoadFrom('wship6.dll'); // WshIp6 dll
+ SafeLoadFrom('ws2_32.dll');
+ SafeLoadFrom('wship6.dll');
end;
+{$ENDIF}
-var
- WSAData: TWSAData;
-
- { TConnectThread }
-
+{ TConnectThread }
procedure TConnectThread.ProcessEvent;
begin
- ConnectResult := Connect(Line.FHandle, Line.AddrResult^.ai_addr^, Line.AddrResult^.ai_addrlen);
+{$IFDEF MSWINDOWS}
+ ConnectResult := Connect(Line.FHandle, Line.AddrResult^.ai_addr^,
+ Line.AddrResult^.ai_addrlen);
+{$ELSE}
+ ConnectResult := Connect(Line.FHandle, Line.AddrResult^.ai_addr^,
+ Line.AddrResult^.ai_addrlen);
+{$ENDIF}
end;
initialization
-WSAStartup(MakeWord(2, 2), WSAData); // Require WinSock 2 version
+{$IFDEF MSWINDOWS}
-AttachAddrInfo;
+var
+ WSAData: TWSAData;
+begin
+ WSAStartup(MakeWord(2, 2), WSAData);
+ AttachAddrInfo;
+end;
+{$ENDIF}
finalization
+{$IFDEF MSWINDOWS}
if ExtDllHandle <> 0 then
FreeLibrary(ExtDllHandle);
-
WSACleanup;
-
{$ENDIF}
end.
diff --git a/Source/ncSockets.pas b/Source/ncSockets.pas
index 8d832d8..4083422 100644
--- a/Source/ncSockets.pas
+++ b/Source/ncSockets.pas
@@ -7,6 +7,13 @@
// This unit creates a TCP Server and TCP Client socket, along with their
// threads dealing with reading from the socket
//
+// 14/01/2025 - by J.Pauwels
+// - Defined DefReadBufferLen as a new property
+// - Ajust TncCustomTCPServer.DataSocketDisconnected
+// - Explicitly set this unit to use TCP
+// - Update Client Send method so data cannot be send while socket is inactive
+// - Added IPV6 support
+//
// 9/8/2020
// - Added a ShutDownLine in the TCPServer component so as to allow to
// shutdown a line even when within a read operation
@@ -49,7 +56,7 @@ interface
const
DefPort = 16233;
- DefHost = 'LocalHost';
+ DefHost = '';
DefReadBufferLen = 1024 * 1024; // 1 MB
DefReaderThreadPriority = ntpNormal;
DefCntReconnectInterval = 1000;
@@ -57,19 +64,31 @@ interface
DefUseReaderThread = True;
DefNoDelay = False;
DefKeepAlive = True;
+ DefFamily = afIPv4;
resourcestring
ECannotSetPortWhileConnectionIsActiveStr = 'Cannot set Port property whilst the connection is active';
ECannotSetHostWhileConnectionIsActiveStr = 'Cannot set Host property whilst the connection is active';
+ ECannotSendWhileSocketInactiveStr = 'Cannot send data while socket is inactive';
ECannotSetUseReaderThreadWhileActiveStr = 'Cannot set UseReaderThread property whilst the connection is active';
ECannotReceiveIfUseReaderThreadStr =
'Cannot receive data if UseReaderThread is set. Use OnReadData event handler to get the data or set UseReaderThread property to false';
+ ECannotSetFamilyWhileConnectionIsActiveStr = 'Cannot set Family property whilst the connection is active';
-type
+ type
EPropertySetError = class(Exception);
ENonActiveSocket = class(Exception);
ECannotReceiveIfUseReaderThread = class(Exception);
+ // We bring in TncLine so that a form that uses our components does
+ // not have to reference ncLines unit to get the type
+ TncLine = ncLines.TncLine;
+
+ // We make a descendant of TncLine so that we can access the API functions.
+ // These API functions are not made puclic in TncLine so that the user cannot
+ // mangle up the line
+ TncLineInternal = class(TncLine);
+
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TThreadLineList
// Thread safe object, used by the main components
@@ -102,15 +121,23 @@ TThreadLineList = class
TncTCPBase = class(TComponent)
private
FInitActive: Boolean;
+ FFamily: TAddressType;
FPort: Integer;
FEventsUseMainThread: Boolean;
FNoDelay: Boolean;
FKeepAlive: Boolean;
+ FReadBufferLen: Integer; // Update
FOnConnected: TncOnConnectDisconnect;
FOnDisconnected: TncOnConnectDisconnect;
FOnReadData: TncOnReadData;
+ FLine: TncLine;
+ function GetReadBufferLen: Integer; // Update
+ procedure SetReadBufferLen(const Value: Integer); // Update
function GetActive: Boolean; virtual; abstract;
procedure SetActive(const Value: Boolean);
+ function GetFamily: TAddressType;
+ procedure SetFamily(const Value: TAddressType);
+
function GetPort: Integer;
procedure SetPort(const Value: Integer);
function GetReaderThreadPriority: TncThreadPriority;
@@ -130,12 +157,16 @@ TncTCPBase = class(TComponent)
ReadBuf: TBytes;
procedure Loaded; override;
function CreateLineObject: TncLine; virtual;
+ property Line: TncLine read FLine;
public
LineProcessor: TncReadyThread;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
+ function Kind: TSocketType; virtual;
+
property Active: Boolean read GetActive write SetActive default False;
+ property Family: TAddressType read GetFamily write SetFamily default afIPv4;
property Port: Integer read GetPort write SetPort default DefPort;
property ReaderThreadPriority: TncThreadPriority read GetReaderThreadPriority write SetReaderThreadPriority default DefReaderThreadPriority;
property EventsUseMainThread: Boolean read GetEventsUseMainThread write SetEventsUseMainThread default DefEventsUseMainThread;
@@ -145,6 +176,7 @@ TncTCPBase = class(TComponent)
property OnConnected: TncOnConnectDisconnect read FOnConnected write FOnConnected;
property OnDisconnected: TncOnConnectDisconnect read FOnDisconnected write FOnDisconnected;
property OnReadData: TncOnReadData read FOnReadData write FOnReadData;
+ property ReadBufferLen: Integer read GetReadBufferLen write SetReadBufferLen default DefReadBufferLen; // Update
published
end;
@@ -190,6 +222,7 @@ TncCustomTCPClient = class(TncTCPBase)
TncTCPClient = class(TncCustomTCPClient)
published
property Active;
+ property Family;
property Port;
property Host;
property ReaderThreadPriority;
@@ -197,6 +230,7 @@ TncTCPClient = class(TncCustomTCPClient)
property UseReaderThread;
property NoDelay;
property KeepAlive;
+ property ReadBufferLen;
property Reconnect;
property ReconnectInterval;
property OnConnected;
@@ -246,12 +280,14 @@ TncTCPServer = class(TncCustomTCPServer)
public
published
property Active;
+ property Family;
property Port;
property ReaderThreadPriority;
property EventsUseMainThread;
property UseReaderThread;
property NoDelay;
property KeepAlive;
+ property ReadBufferLen; // Update
property OnConnected;
property OnDisconnected;
property OnReadData;
@@ -269,15 +305,6 @@ TncServerProcessor = class(TncReadyThread)
procedure ProcessEvent; override;
end;
- // We bring in TncLine so that a form that uses our components does
- // not have to reference ncLines unit to get the type
- TncLine = ncLines.TncLine;
-
- // We make a descendant of TncLine so that we can access the API functions.
- // These API functions are not made puclic in TncLine so that the user cannot
- // mangle up the line
- TncLineInternal = class(TncLine);
-
implementation
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -392,16 +419,24 @@ constructor TncTCPBase.Create(AOwner: TComponent);
ShutDownLock := TCriticalSection.Create;
FInitActive := False;
+ FFamily := DefFamily;
FPort := DefPort;
FEventsUseMainThread := DefEventsUseMainThread;
FUseReaderThread := DefUseReaderThread;
FNoDelay := DefNoDelay;
FKeepAlive := DefKeepAlive;
+ FReadBufferLen := DefReadBufferLen; // Update
FOnConnected := nil;
FOnDisconnected := nil;
FOnReadData := nil;
SetLength(ReadBuf, DefReadBufferLen);
+
+end;
+
+function TncTCPBase.Kind: TSocketType;
+begin
+ Result := stTCP;
end;
destructor TncTCPBase.Destroy;
@@ -422,6 +457,8 @@ procedure TncTCPBase.Loaded;
function TncTCPBase.CreateLineObject: TncLine;
begin
Result := TncLineInternal.Create;
+ TncLineInternal(Result).SetKind(Kind);
+ TncLineInternal(Result).SetFamily(FFamily);
end;
procedure TncTCPBase.SetActive(const Value: Boolean);
@@ -437,6 +474,39 @@ procedure TncTCPBase.SetActive(const Value: Boolean);
end;
end;
+function TncTCPBase.GetFamily: TAddressType;
+begin
+ PropertyLock.Acquire;
+ try
+ Result := FFamily;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+procedure TncTCPBase.SetFamily(const Value: TAddressType);
+begin
+ if not (csLoading in ComponentState) then
+ begin
+ if Active then
+ raise EPropertySetError.Create(ECannotSetFamilyWhileConnectionIsActiveStr);
+ end;
+
+ PropertyLock.Acquire;
+ try
+ // Update base class family
+ FFamily := Value;
+
+ // Update the Line's family
+ if FLine <> nil then
+ begin
+ TncLineInternal(FLine).SetFamily(Value);
+ end;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
function TncTCPBase.GetPort: Integer;
begin
PropertyLock.Acquire;
@@ -559,6 +629,29 @@ procedure TncTCPBase.SetKeepAlive(const Value: Boolean);
end;
end;
+// Update
+function TncTCPBase.GetReadBufferLen: Integer;
+begin
+ PropertyLock.Acquire;
+ try
+ Result := FReadBufferLen;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+// Update
+procedure TncTCPBase.SetReadBufferLen(const Value: Integer);
+begin
+ PropertyLock.Acquire;
+ try
+ FReadBufferLen := Value;
+ SetLength(ReadBuf, FReadBufferLen);
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{ TncCustomTCPClient }
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -575,7 +668,13 @@ constructor TncCustomTCPClient.Create(AOwner: TComponent);
LastConnectAttempt := TStopWatch.GetTimeStamp;
WasConnected := False;
+ // Create Line with correct family
Line := CreateLineObject;
+ if Line.Family <> FFamily then
+ begin
+ TncLineInternal(Line).SetFamily(FFamily);
+ end;
+
TncLineInternal(Line).OnConnected := DataSocketConnected;
TncLineInternal(Line).OnDisconnected := DataSocketDisconnected;
@@ -589,6 +688,7 @@ constructor TncCustomTCPClient.Create(AOwner: TComponent);
LineProcessor.WaitForReady;
end;
+
destructor TncCustomTCPClient.Destroy;
begin
Active := False;
@@ -605,12 +705,20 @@ destructor TncCustomTCPClient.Destroy;
procedure TncCustomTCPClient.DoActivate(aActivate: Boolean);
begin
+
if aActivate = GetActive then
Exit;
if aActivate then
begin
+ // Verify family setting before creating handle
+ if Line.Family <> FFamily then
+ begin
+ TncLineInternal(Line).SetFamily(FFamily);
+ end;
+
TncLineInternal(Line).CreateClientHandle(FHost, FPort);
+
// if there were no exceptions, and line is still not active,
// that means the user has deactivated it in the OnConnect handler
if not Line.Active then
@@ -641,9 +749,10 @@ procedure TncCustomTCPClient.DataSocketConnected(aLine: TncLine);
end;
try
- TncLineInternal(Line).SetReceiveSize(1048576);
- TncLineInternal(Line).SetWriteSize(1048576);
- TncLineInternal(Line).SetReceiveSize(20 * 1048576);
+ TncLineInternal(Line).SetReceiveSize(1048576); // 1MB
+ TncLineInternal(Line).SetWriteSize(1048576); // 1MB
+ //TncLineInternal(Line).SetReceiveSize(20 * 1048576);
+
except
end;
@@ -669,9 +778,12 @@ procedure TncCustomTCPClient.DataSocketDisconnected(aLine: TncLine);
end;
end;
+
procedure TncCustomTCPClient.Send(const aBuf; aBufSize: Integer);
begin
- Active := True;
+ if not Active then
+ raise EPropertySetError.Create(ECannotSendWhileSocketInactiveStr);
+
TncLineInternal(Line).SendBuffer(aBuf, aBufSize);
end;
@@ -890,6 +1002,11 @@ constructor TncCustomTCPServer.Create(AOwner: TComponent);
inherited Create(AOwner);
Listener := CreateLineObject;
+ if Listener.Family <> FFamily then
+ begin
+ TncLineInternal(Listener).SetFamily(FFamily);
+ end;
+
TncLineInternal(Listener).OnConnected := DataSocketConnected;
TncLineInternal(Listener).OnDisconnected := DataSocketDisconnected;
@@ -933,23 +1050,31 @@ procedure TncCustomTCPServer.DoActivate(aActivate: Boolean);
if aActivate then
begin
+ // Verify family setting before creating handle
+ if Assigned(Listener) and (Listener.Family <> FFamily) then
+ begin
+ TncLineInternal(Listener).SetFamily(FFamily);
+ end;
TncLineInternal(Listener).CreateServerHandle(FPort);
end
else
begin
- TncLineInternal(Listener).DestroyHandle;
+ if Assigned(Listener) then
+ TncLineInternal(Listener).DestroyHandle;
- // Delphi complains about the free that it does nothing except nil the variable
- // That is under the mostly forgettable and thankgoodness "gotten rid off"
- // ARC compilers...
+ // Cleanup connected sockets
{$HINTS OFF}
DataSockets := Lines.LockListNoCopy;
try
for i := 0 to DataSockets.Count - 1 do
try
- TncLineInternal(DataSockets.Lines[i]).DestroyHandle;
- TncLineInternal(DataSockets.Lines[i]).Free;
+ if Assigned(DataSockets.Lines[i]) then
+ begin
+ TncLineInternal(DataSockets.Lines[i]).DestroyHandle;
+ DataSockets.Lines[i].Free;
+ end;
except
+ //
end;
DataSockets.Clear;
finally
@@ -1026,6 +1151,8 @@ procedure TncCustomTCPServer.DataSocketConnected(aLine: TncLine);
end;
end;
+// Update : Moves the handle removal before the disconnect event handling
+// This prevents other threads from trying to use the handle while the disconnect event is processing.
procedure TncCustomTCPServer.DataSocketDisconnected(aLine: TncLine);
var
i: Integer;
@@ -1034,19 +1161,26 @@ procedure TncCustomTCPServer.DataSocketDisconnected(aLine: TncLine);
SetLength(ReadSocketHandles, 0)
else
begin
+ // First remove the handle to prevent further processing
+ PropertyLock.Acquire;
+ try
+ for i := 0 to High(ReadSocketHandles) do
+ if ReadSocketHandles[i] = aLine.Handle then
+ begin
+ ReadSocketHandles[i] := ReadSocketHandles[High(ReadSocketHandles)];
+ SetLength(ReadSocketHandles, Length(ReadSocketHandles) - 1);
+ Break;
+ end;
+ finally
+ PropertyLock.Release;
+ end;
+
+ // Then handle disconnect event
if Assigned(OnDisconnected) then
try
OnDisconnected(Self, aLine);
except
end;
-
- for i := 0 to High(ReadSocketHandles) do
- if ReadSocketHandles[i] = aLine.Handle then
- begin
- ReadSocketHandles[i] := ReadSocketHandles[High(ReadSocketHandles)];
- SetLength(ReadSocketHandles, Length(ReadSocketHandles) - 1);
- Break;
- end;
end;
end;
@@ -1260,3 +1394,5 @@ procedure TncServerProcessor.ProcessEvent;
end;
end.
+
+
diff --git a/Source/ncSources.pas b/Source/ncSources.pas
index 4029540..54a71a7 100644
--- a/Source/ncSources.pas
+++ b/Source/ncSources.pas
@@ -25,6 +25,10 @@
// These components have built in encryption and compression, set by the
// corresponding properties.
//
+// 14/01/2025 - by J.Pauwels
+// - Explicitly set this unit to use TCP
+// - Added IPV6 support
+//
// 12/8/2020
// - Complete re-engineering of the base component
//
@@ -184,6 +188,9 @@ TncSourceBase = class(TComponent, IncCommandHandler)
function GetReaderThreadPriority: TncThreadPriority;
procedure SetReaderThreadPriority(const Value: TncThreadPriority);
+ function GetFamily: TAddressType;
+ procedure SetFamily(const Value: TAddressType);
+
// For implementing the IncCommandHandler interface
function GetComponentName: string;
function GetOnConnected: TncOnSourceConnectDisconnect;
@@ -264,6 +271,7 @@ TncSourceBase = class(TComponent, IncCommandHandler)
property ReaderThreadPriority: TncThreadPriority read GetReaderThreadPriority write SetReaderThreadPriority default DefReaderThreadPriority;
property NoDelay: Boolean read GetNoDelay write SetNoDelay default True;
property KeepAlive: Boolean read GetKeepAlive write SetKeepAlive default True;
+ property Family: TAddressType read GetFamily write SetFamily default afIPv4;
// New properties for sources
property CommandProcessorThreadPriority: TncThreadPriority read GetCommandProcessorThreadPriority write SetCommandProcessorThreadPriority
@@ -365,6 +373,7 @@ constructor TncSourceLine.Create;
function TncSourceLine.CreateLineObject: TncLine;
begin
Result := TncSourceLine.Create; // Create its own kind of objects
+ TncSourceLine(Result).SetKind(stTCP); // Explicitly set to TCP
end;
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -865,6 +874,16 @@ procedure TncSourceBase.SetActive(const Value: Boolean);
Socket.Active := Value;
end;
+function TncSourceBase.GetFamily: TAddressType;
+begin
+ Result := Socket.Family;
+end;
+
+procedure TncSourceBase.SetFamily(const Value: TAddressType);
+begin
+ Socket.Family := Value;
+end;
+
function TncSourceBase.GetKeepAlive: Boolean;
begin
Result := Socket.KeepAlive;
@@ -1259,6 +1278,7 @@ TncTCPClientSourceSocket = class(TncTCPClient)
function TncTCPClientSourceSocket.CreateLineObject: TncLine;
begin
Result := TncSourceLine.Create;
+ TncSourceLine(Result).SetKind(stTCP);
end;
constructor TncClientSource.Create(AOwner: TComponent);
@@ -1268,6 +1288,7 @@ constructor TncClientSource.Create(AOwner: TComponent);
FOnReconnected := nil;
Socket := TncTCPClientSourceSocket.Create(nil);
+ Socket.Family := afIPv4; // Set default family
Socket.Port := DefPort;
Socket.NoDelay := DefNoDelay;
Socket.EventsUseMainThread := False;
@@ -1351,6 +1372,7 @@ TncTCPServerSourceSocket = class(TncTCPServer)
function TncTCPServerSourceSocket.CreateLineObject: TncLine;
begin
Result := TncSourceLine.Create;
+ TncSourceLine(Result).SetKind(stTCP);
end;
constructor TncServerSource.Create(AOwner: TComponent);
@@ -1358,6 +1380,7 @@ constructor TncServerSource.Create(AOwner: TComponent);
inherited Create(AOwner);
Socket := TncTCPServerSourceSocket.Create(nil);
+ Socket.Family := afIPv4; // Set default family
Socket.NoDelay := DefNoDelay;
Socket.Port := DefPort;
Socket.EventsUseMainThread := False;
@@ -1383,3 +1406,4 @@ procedure TncServerSource.ShutDownLine(aLine: TncLine);
end;
end.
+
diff --git a/Source/ncUDPSockets.pas b/Source/ncUDPSockets.pas
new file mode 100644
index 0000000..e7d8b75
--- /dev/null
+++ b/Source/ncUDPSockets.pas
@@ -0,0 +1,1098 @@
+unit ncUDPSockets;
+// /////////////////////////////////////////////////////////////////////////////
+//
+// NetCom7 Package - UDP Socket Components
+//
+// This unit implements UDP Server and UDP Client components
+//
+// 14/1/2025
+// - Initial creation
+// Currently implemented :
+// - Broadcast
+//
+// Written by J.Pauwels
+//
+// /////////////////////////////////////////////////////////////////////////////
+
+{$IF CompilerVersion >= 21.0}
+{$WEAKLINKRTTI ON}
+{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
+{$ENDIF}
+
+interface
+
+uses
+{$IFDEF MSWINDOWS}
+ Winapi.Windows, Winapi.Winsock2,
+{$ELSE}
+ Posix.SysSocket, Posix.Unistd,
+{$ENDIF}
+ System.Classes, System.SysUtils, System.SyncObjs, System.Math, System.Diagnostics, System.TimeSpan,
+ ncLines, ncSocketList, ncThreads, ncIPUtils;
+
+const
+ DefPort = 16233;
+ DefHost = '';
+ DefReadBufferLen = 64 * 1024; // 64KB default for UDP
+ DefReaderThreadPriority = ntpNormal;
+ DefEventsUseMainThread = False;
+ DefUseReaderThread = True;
+ DefBroadcast = False;
+ DefFamily = afIPv4;
+
+resourcestring
+ ECannotSetPortWhileSocketActiveStr = 'Cannot set Port property while socket is active';
+ ECannotSetHostWhileSocketActiveStr = 'Cannot set Host property while socket is active';
+ ECannotSendWhileSocketInactiveStr = 'Cannot send data while socket is inactive';
+ ECannotSetUseReaderThreadWhileSocketActiveStr = 'Cannot set UseReaderThread property while socket is active';
+ ECannotReceiveIfUseReaderThreadStr = 'Cannot receive data if UseReaderThread is set. Use OnReadDatagram event handler to get the data or set UseReaderThread property to false';
+ ECannotSetFamilyWhileConnectionIsActiveStr = 'Cannot set Family property whilst the connection is active';
+type
+ EPropertySetError = class(Exception);
+
+ // Event types for UDP
+ TncOnDatagramEvent = procedure(Sender: TObject; aLine: TncLine;const aBuf: TBytes; aBufCount: Integer;const SenderAddr: TSockAddrStorage) of object;
+
+
+ // Base UDP Socket class
+ TncUDPBase = class(TComponent)
+ private
+ FInitActive: Boolean;
+ FFamily: TAddressType;
+ FPort: Integer;
+ FEventsUseMainThread: Boolean;
+ FBroadcast: Boolean;
+ FLine: TncLine;
+ FReadBufferLen: Integer;
+ FOnReadDatagram: TncOnDatagramEvent;
+ function GetReadBufferLen: Integer;
+ procedure SetReadBufferLen(const Value: Integer);
+ function GetActive: Boolean; virtual; abstract;
+ procedure SetActive(const Value: Boolean);
+ function GetFamily: TAddressType;
+ procedure SetFamily(const Value: TAddressType);
+ function GetPort: Integer;
+ procedure SetPort(const Value: Integer);
+ function GetReaderThreadPriority: TncThreadPriority;
+ procedure SetReaderThreadPriority(const Value: TncThreadPriority);
+ function GetBroadcast: Boolean;
+ procedure SetBroadcast(const Value: Boolean);
+
+ private
+ FUseReaderThread: Boolean;
+ procedure DoActivate(aActivate: Boolean); virtual; abstract;
+ procedure SetUseReaderThread(const Value: Boolean);
+ protected
+ PropertyLock: TCriticalSection;
+ ReadBuf: TBytes;
+ procedure Loaded; override;
+ function CreateLineObject: TncLine; virtual;
+ function GetLine: TncLine; virtual; abstract;
+ public
+ LineProcessor: TncReadyThread;
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+
+ function Kind: TSocketType; virtual;
+
+ property Active: Boolean read GetActive write SetActive default False;
+ property Family: TAddressType read GetFamily write SetFamily default afIPv4;
+ property Port: Integer read GetPort write SetPort default DefPort;
+ property ReaderThreadPriority: TncThreadPriority read GetReaderThreadPriority write SetReaderThreadPriority default DefReaderThreadPriority;
+ property EventsUseMainThread: Boolean read FEventsUseMainThread write FEventsUseMainThread default DefEventsUseMainThread;
+ property UseReaderThread: Boolean read FUseReaderThread write SetUseReaderThread default DefUseReaderThread;
+ property Broadcast: Boolean read GetBroadcast write SetBroadcast default DefBroadcast;
+ property OnReadDatagram: TncOnDatagramEvent read FOnReadDatagram write FOnReadDatagram;
+ property ReadBufferLen: Integer read GetReadBufferLen write SetReadBufferLen default DefReadBufferLen;
+ published
+ end;
+
+ // UDP Client implementation
+ TncUDPClientProcessor = class;
+
+ TncCustomUDPClient = class(TncUDPBase)
+ private
+ FHost: string;
+ function GetActive: Boolean; override;
+ procedure SetHost(const Value: string);
+ function GetHost: string;
+ protected
+ procedure DoActivate(aActivate: Boolean); override;
+ function GetLine: TncLine; override;
+ public
+ ReadSocketHandles: TSocketHandleArray;
+ Line: TncLine;
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure SendTo(const aBuf; aBufSize: Integer; const DestAddr: TSockAddrStorage); overload;
+ procedure SendTo(const aBytes: TBytes;const DestAddr: TSockAddrStorage); overload;
+ procedure SendTo(const aStr: string; const DestAddr: TSockAddrStorage); overload;
+ procedure Send(const aBuf; aBufSize: Integer); overload;
+ procedure Send(const aBytes: TBytes); overload;
+ procedure Send(const aStr: string); overload;
+ function Receive(aTimeout: Cardinal = 2000): TBytes;
+ property Host: string read GetHost write SetHost;
+ end;
+
+ TncUDPClient = class(TncCustomUDPClient)
+ published
+ property Active;
+ property Family;
+ property Port;
+ property Host;
+ property ReaderThreadPriority;
+ property EventsUseMainThread;
+ property UseReaderThread;
+ property Broadcast;
+ property ReadBufferLen;
+ property OnReadDatagram;
+ end;
+
+ TncUDPClientProcessor = class(TncReadyThread)
+ private
+ FClientSocket: TncCustomUDPClient;
+ public
+ ReadySocketsChanged: Boolean;
+ constructor Create(aClientSocket: TncCustomUDPClient);
+ procedure ProcessDatagram; inline;
+ procedure ProcessEvent; override;
+ end;
+
+ // UDP Server implementation
+ TncUDPServerProcessor = class;
+
+ TncCustomUDPServer = class(TncUDPBase)
+ private
+ function GetActive: Boolean; override;
+ protected
+ procedure DoActivate(aActivate: Boolean); override;
+ function GetLine: TncLine; override;
+ public
+ ReadSocketHandles: TSocketHandleArray;
+ Line: TncLine;
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure SendTo(const aBuf; aBufSize: Integer; const DestAddr: TSockAddrStorage); overload;
+ procedure SendTo(const aBytes: TBytes;const DestAddr: TSockAddrStorage); overload;
+ procedure SendTo(const aStr: string; const DestAddr: TSockAddrStorage); overload;
+ function Receive(aTimeout: Cardinal = 2000): TBytes;
+ end;
+
+ TncUDPServer = class(TncCustomUDPServer)
+ published
+ property Active;
+ property Family;
+ property Port;
+ property ReaderThreadPriority;
+ property EventsUseMainThread;
+ property UseReaderThread;
+ property Broadcast;
+ property ReadBufferLen;
+ property OnReadDatagram;
+ end;
+
+ TncUDPServerProcessor = class(TncReadyThread)
+ private
+ FServerSocket: TncCustomUDPServer;
+ public
+ ReadySockets: TSocketHandleArray;
+ ReadySocketsChanged: Boolean;
+ constructor Create(aServerSocket: TncCustomUDPServer);
+ procedure ProcessDatagram; inline;
+ procedure ProcessEvent; override;
+ end;
+
+ // We bring in TncLine so that a form that uses our components does
+ // not have to reference ncLines unit to get the type
+ TncLine = ncLines.TncLine;
+
+ // We make a descendant of TncLine so that we can access the API functions.
+ // These API functions are not made puclic in TncLine so that the user cannot
+ // mangle up the line
+ TncLineInternal = class(TncLine);
+
+implementation
+
+{ TncUDPBase }
+
+constructor TncUDPBase.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+
+ PropertyLock := TCriticalSection.Create;
+
+ FInitActive := False;
+ FFamily := DefFamily;
+ FPort := DefPort;
+ FEventsUseMainThread := DefEventsUseMainThread;
+ FUseReaderThread := DefUseReaderThread;
+ FBroadcast := DefBroadcast;
+ FReadBufferLen := DefReadBufferLen;
+ FOnReadDatagram := nil;
+
+ SetLength(ReadBuf, DefReadBufferLen);
+
+end;
+
+function TncUDPBase.Kind: TSocketType;
+begin
+ Result := stUDP;
+end;
+
+destructor TncUDPBase.Destroy;
+begin
+ PropertyLock.Free;
+ inherited Destroy;
+end;
+
+procedure TncUDPBase.Loaded;
+begin
+ inherited Loaded;
+ if FInitActive then
+ DoActivate(True);
+end;
+
+function TncUDPBase.CreateLineObject: TncLine;
+begin
+ Result := TncLine.Create;
+ TncLineInternal(Result).SetKind(Kind);
+ TncLineInternal(Result).SetFamily(FFamily);
+end;
+
+procedure TncUDPBase.SetActive(const Value: Boolean);
+begin
+ PropertyLock.Acquire;
+ try
+ if not(csLoading in ComponentState) then
+ DoActivate(Value);
+ FInitActive := GetActive;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+function TncUDPBase.GetFamily: TAddressType;
+begin
+ PropertyLock.Acquire;
+ try
+ Result := FFamily;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+procedure TncUDPBase.SetFamily(const Value: TAddressType);
+begin
+ if not(csLoading in ComponentState) then
+ begin
+ if Active then
+ raise EPropertySetError.Create
+ (ECannotSetFamilyWhileConnectionIsActiveStr);
+ end;
+
+ PropertyLock.Acquire;
+ try
+ // Update base class family
+ FFamily := Value;
+
+ // Update the Line's family
+ if FLine <> nil then
+ begin
+ TncLineInternal(FLine).SetFamily(Value);
+ end;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+function TncUDPBase.GetPort: Integer;
+begin
+ PropertyLock.Acquire;
+ try
+ Result := FPort;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+procedure TncUDPBase.SetPort(const Value: Integer);
+begin
+ if not(csLoading in ComponentState) then
+ if Active then
+ raise EPropertySetError.Create(ECannotSetPortWhileSocketActiveStr);
+
+ PropertyLock.Acquire;
+ try
+ FPort := Value;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+function TncUDPBase.GetReaderThreadPriority: TncThreadPriority;
+begin
+ PropertyLock.Acquire;
+ try
+ Result := ToNcThreadPriority(LineProcessor.Priority);
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+procedure TncUDPBase.SetReaderThreadPriority(const Value: TncThreadPriority);
+begin
+ PropertyLock.Acquire;
+ try
+ try
+ LineProcessor.Priority := FromNcThreadPriority(Value);
+ except
+ // Some android devices cannot handle changing priority
+ end;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+function TncUDPBase.GetBroadcast: Boolean;
+begin
+ PropertyLock.Acquire;
+ try
+ Result := FBroadcast;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+procedure TncUDPBase.SetBroadcast(const Value: Boolean);
+begin
+ PropertyLock.Acquire;
+ try
+ FBroadcast := Value;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+procedure TncUDPBase.SetUseReaderThread(const Value: Boolean);
+begin
+ if not(csLoading in ComponentState) then
+ if Active then
+ raise EPropertySetError.Create(ECannotSetUseReaderThreadWhileSocketActiveStr);
+
+ PropertyLock.Acquire;
+ try
+ FUseReaderThread := Value;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+function TncUDPBase.GetReadBufferLen: Integer;
+begin
+ PropertyLock.Acquire;
+ try
+ Result := FReadBufferLen;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+procedure TncUDPBase.SetReadBufferLen(const Value: Integer);
+begin
+ PropertyLock.Acquire;
+ try
+ FReadBufferLen := Value;
+ SetLength(ReadBuf, FReadBufferLen);
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+{ TncCustomUDPClient }
+
+constructor TncCustomUDPClient.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+
+ FHost := DefHost;
+
+ Line := CreateLineObject;
+
+ // Create Line with correct family
+ Line := CreateLineObject;
+ if Line.Family <> FFamily then
+ begin
+ TncLineInternal(Line).SetFamily(FFamily);
+ end;
+
+ LineProcessor := TncUDPClientProcessor.Create(Self);
+ try
+ LineProcessor.Priority := FromNcThreadPriority(DefReaderThreadPriority);
+ except
+ // Some Android devices do not like this
+ end;
+end;
+
+destructor TncCustomUDPClient.Destroy;
+begin
+ Active := False;
+
+ LineProcessor.Terminate;
+ LineProcessor.WakeupEvent.SetEvent;
+ LineProcessor.WaitFor;
+ LineProcessor.Free;
+
+ Line.Free;
+
+ inherited Destroy;
+end;
+
+function TncCustomUDPClient.GetLine: TncLine;
+begin
+ Result := Line;
+end;
+
+procedure TncCustomUDPClient.DoActivate(aActivate: Boolean);
+begin
+ // Exit if socket is already in requested state
+ if aActivate = GetActive then
+ Exit;
+
+ if aActivate then
+ begin
+ try
+
+ // Verify family setting before creating handle
+ if Line.Family <> FFamily then
+ begin
+ TncLineInternal(Line).SetFamily(FFamily);
+ end;
+
+ // Create socket handle and establish connection
+ TncLineInternal(Line).CreateClientHandle(FHost, FPort, GetBroadcast);
+
+ // Enable broadcast mode if requested
+ if GetBroadcast then
+ TncLineInternal(Line).EnableBroadcast;
+
+ // Configure socket buffer sizes for optimal performance
+ try
+ TncLineInternal(Line).SetReceiveSize(GetReadBufferLen);
+ TncLineInternal(Line).SetWriteSize(GetReadBufferLen);
+ except
+ on E: Exception do
+ begin
+ TncLineInternal(Line).DestroyHandle;
+ raise;
+ end;
+ end;
+
+ // Initialize socket handle array for reading
+ SetLength(ReadSocketHandles, 1);
+ ReadSocketHandles[0] := Line.Handle;
+
+ // Start reader thread if enabled
+ if UseReaderThread then
+ LineProcessor.Run;
+ except
+ on E: Exception do
+ begin
+ // Clean up on activation failure
+ TncLineInternal(Line).DestroyHandle;
+ SetLength(ReadSocketHandles, 0);
+ raise;
+ end;
+ end;
+ end
+ else
+ begin
+ // Clean up when deactivating
+ TncLineInternal(Line).DestroyHandle;
+ SetLength(ReadSocketHandles, 0);
+ end;
+end;
+
+function TncCustomUDPClient.GetActive: Boolean;
+begin
+ Result := Line.Active;
+end;
+
+function TncCustomUDPClient.GetHost: string;
+begin
+ PropertyLock.Acquire;
+ try
+ Result := FHost;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+procedure TncCustomUDPClient.SetHost(const Value: string);
+begin
+ if not(csLoading in ComponentState) then
+ if Active then
+ raise EPropertySetError.Create(ECannotSetHostWhileSocketActiveStr);
+
+ PropertyLock.Acquire;
+ try
+ FHost := Value;
+ finally
+ PropertyLock.Release;
+ end;
+end;
+
+procedure TncCustomUDPClient.Send(const aBuf; aBufSize: Integer);
+var
+ storage: TSockAddrStorage;
+ addrV4: PSockAddrIn;
+ addrV6: PSockAddrIn6;
+begin
+ if not Active then
+ raise EPropertySetError.Create(ECannotSendWhileSocketInactiveStr);
+
+ case Family of
+ afIPv4:
+ begin
+ if GetBroadcast then
+ begin
+ FillChar(storage, SizeOf(storage), 0);
+ storage.ss_family := AF_INET;
+
+ addrV4 := PSockAddrIn(@storage);
+ addrV4^.sin_family := AF_INET;
+ addrV4^.sin_port := htons(FPort);
+
+ // Use Winsock API directly for IPv4 broadcast
+ var addr := inet_addr(PAnsiChar(AnsiString(FHost)));
+ if addr <> INADDR_NONE then
+ addrV4^.sin_addr.S_addr := addr
+ else
+ raise Exception.Create('Invalid IPv4 address format');
+
+ SendTo(aBuf, aBufSize, storage);
+ end
+ else
+ TncLineInternal(Line).SendBuffer(aBuf, aBufSize);
+ end;
+
+ afIPv6:
+ begin
+ if GetBroadcast then
+ raise Exception.Create('Broadcast is not supported in IPv6. Use multicast instead.')
+ else if FHost = '' then
+ raise Exception.Create('Host address cannot be empty for IPv6')
+ else
+ begin
+ // Validate IPv6 address format
+ if not TncIPUtils.IsIPv6ValidAddress(FHost) then
+ raise Exception.Create('Invalid IPv6 address format');
+
+ FillChar(storage, SizeOf(storage), 0);
+ storage.ss_family := AF_INET6;
+
+ addrV6 := PSockAddrIn6(@storage);
+ addrV6^.sin6_family := AF_INET6;
+ addrV6^.sin6_port := htons(FPort);
+
+ // Handle link-local address with scope ID
+ if TncIPUtils.IsLinkLocal(FHost) then
+ begin
+ var scopePos := Pos('%', FHost);
+ if scopePos > 0 then
+ begin
+ var hostAddr := Copy(FHost, 1, scopePos - 1);
+ var scope := Copy(FHost, scopePos + 1, Length(FHost));
+ var scopeID: Cardinal;
+ if TryStrToUInt(scope, scopeID) then
+ begin
+ addrV6^.sin6_scope_id := scopeID;
+ // Convert the address part without scope ID
+ if not TncIPUtils.StringToAddress(hostAddr, addrV6^.sin6_addr) then
+ raise Exception.Create('Invalid IPv6 address format');
+ end
+ else
+ raise Exception.Create('Invalid IPv6 scope ID');
+ end
+ else if not TncIPUtils.StringToAddress(FHost, addrV6^.sin6_addr) then
+ raise Exception.Create('Invalid IPv6 address format');
+ end
+ else if not TncIPUtils.StringToAddress(FHost, addrV6^.sin6_addr) then
+ raise Exception.Create('Invalid IPv6 address format');
+
+ SendTo(aBuf, aBufSize, storage);
+ end;
+ end;
+ end;
+end;
+
+procedure TncCustomUDPClient.Send(const aBytes: TBytes);
+begin
+ if Length(aBytes) > 0 then
+ Send(aBytes[0], Length(aBytes));
+end;
+
+procedure TncCustomUDPClient.Send(const aStr: string);
+begin
+ Send(BytesOf(aStr));
+end;
+
+// 1. Base SendTo that does the actual sending
+procedure TncCustomUDPClient.SendTo(const aBuf; aBufSize: Integer;
+ const DestAddr: TSockAddrStorage);
+var
+ AddrLen: Integer;
+ {$IFDEF MSWINDOWS}
+ BytesSent: Integer;
+ {$ELSE}
+ BytesSent: ssize_t;
+ {$ENDIF}
+ DestIP: string;
+begin
+ if not Active then
+ raise EPropertySetError.Create(ECannotSendWhileSocketInactiveStr);
+
+ try
+ // Get destination address for logging/error reporting
+ DestIP := TncIPUtils.GetIPFromStorage(DestAddr);
+
+ // Set proper address length based on family
+ case DestAddr.ss_family of
+ AF_INET: AddrLen := SizeOf(TSockAddr);
+ AF_INET6: AddrLen := SizeOf(TSockAddrIn6);
+ else
+ AddrLen := SizeOf(TSockAddrStorage);
+ end;
+
+ {$IFDEF MSWINDOWS}
+ BytesSent := Winapi.Winsock2.sendto(Line.Handle, aBuf, aBufSize, 0,
+ Psockaddr(@DestAddr), AddrLen);
+ if BytesSent = SOCKET_ERROR then
+ raise Exception.CreateFmt('Failed to send to %s: %s',
+ [DestIP, SysErrorMessage(WSAGetLastError)]);
+ {$ELSE}
+ BytesSent := Posix.SysSocket.sendto(Line.Handle, @aBuf, aBufSize, 0,
+ Psockaddr(@DestAddr), AddrLen);
+ if BytesSent < 0 then
+ raise Exception.CreateFmt('Failed to send to %s: %s',
+ [DestIP, SysErrorMessage(GetLastError)]);
+ {$ENDIF}
+ except
+ on E: EIPError do
+ raise Exception.Create('Invalid destination address: ' + E.Message);
+ end;
+end;
+
+// 2. SendTo for byte arrays
+procedure TncCustomUDPClient.SendTo(const aBytes: TBytes;
+ const DestAddr: TSockAddrStorage);
+begin
+ if Length(aBytes) > 0 then
+ SendTo(aBytes[0], Length(aBytes), DestAddr);
+end;
+
+// 3. SendTo for strings
+procedure TncCustomUDPClient.SendTo(const aStr: string; const DestAddr: TSockAddrStorage);
+var
+ bytes: TBytes;
+ len: Integer;
+begin
+ bytes := BytesOf(aStr);
+ len := Length(bytes);
+ if len > 0 then
+ SendTo(bytes[0], len, DestAddr);
+end;
+
+function TncCustomUDPClient.Receive(aTimeout: Cardinal = 2000): TBytes;
+var
+ BufRead: Integer;
+ SenderAddr: TSockAddrStorage;
+ SenderAddrLen: Integer;
+ SenderIP: string;
+begin
+ if UseReaderThread then
+ raise Exception.Create(ECannotReceiveIfUseReaderThreadStr);
+
+ Active := True;
+
+ if not ReadableAnySocket([Line.Handle], aTimeout) then
+ begin
+ SetLength(Result, 0);
+ Exit;
+ end;
+
+ SenderAddrLen := SizeOf(TSockAddrStorage);
+ FillChar(SenderAddr, SenderAddrLen, 0);
+
+ BufRead := recvfrom(Line.Handle, ReadBuf[0], Length(ReadBuf), 0,
+ PSockAddr(@SenderAddr)^, SenderAddrLen);
+
+ try
+ if BufRead > 0 then
+ begin
+ // Get sender IP for logging if needed
+ SenderIP := TncIPUtils.GetIPFromStorage(SenderAddr);
+ Result := Copy(ReadBuf, 0, BufRead);
+ end
+ else if BufRead = 0 then
+ begin
+ SetLength(Result, 0);
+ // Optional: raise Exception.Create('Connection closed by peer');
+ end
+ else
+ begin
+ SetLength(Result, 0);
+ {$IFDEF MSWINDOWS}
+ raise Exception.Create('Receive error: ' + SysErrorMessage(WSAGetLastError));
+ {$ELSE}
+ raise Exception.Create('Receive error: ' + SysErrorMessage(GetLastError));
+ {$ENDIF}
+ end;
+ except
+ on E: EIPError do
+ begin
+ SetLength(Result, 0);
+ raise Exception.Create('Invalid sender address: ' + E.Message);
+ end;
+ end;
+end;
+
+{ TncUDPClientProcessor }
+
+constructor TncUDPClientProcessor.Create(aClientSocket: TncCustomUDPClient);
+begin
+ FClientSocket := aClientSocket;
+ ReadySocketsChanged := False;
+ inherited Create;
+end;
+
+procedure TncUDPClientProcessor.ProcessDatagram;
+var
+ BufRead: Integer;
+ SenderAddr: TSockAddrStorage;
+ SenderAddrLen: Integer;
+begin
+ // Initialize sender address structure
+ SenderAddrLen := SizeOf(TSockAddrStorage);
+ FillChar(SenderAddr, SenderAddrLen, 0);
+
+ // Receive datagram with proper address structure
+ BufRead := recvfrom(FClientSocket.Line.Handle,
+ FClientSocket.ReadBuf[0],
+ Length(FClientSocket.ReadBuf),
+ 0,
+ PSockAddr(@SenderAddr)^,
+ SenderAddrLen);
+
+ if (BufRead > 0) and Assigned(FClientSocket.OnReadDatagram) then
+ try
+ FClientSocket.OnReadDatagram(FClientSocket,
+ FClientSocket.Line,
+ FClientSocket.ReadBuf,
+ BufRead,
+ SenderAddr);
+ except
+ end;
+end;
+
+procedure TncUDPClientProcessor.ProcessEvent;
+begin
+ while (not Terminated) do
+ try
+ if FClientSocket.Line.Active then
+ begin
+ if ReadableAnySocket(FClientSocket.ReadSocketHandles, 100) then
+ begin
+ if ReadySocketsChanged then
+ begin
+ ReadySocketsChanged := False;
+ Continue;
+ end;
+ if FClientSocket.EventsUseMainThread then
+ Synchronize(ProcessDatagram)
+ else
+ ProcessDatagram;
+ end;
+ end
+ else
+ Exit;
+ except
+ // Continue processing even after errors
+ end;
+end;
+
+{ TncCustomUDPServer }
+
+constructor TncCustomUDPServer.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+
+ Line := CreateLineObject;
+
+ // Create Line with correct family
+ Line := CreateLineObject;
+ if Line.Family <> FFamily then
+ begin
+ TncLineInternal(Line).SetFamily(FFamily);
+ end;
+
+ LineProcessor := TncUDPServerProcessor.Create(Self);
+ try
+ LineProcessor.Priority := FromNcThreadPriority(DefReaderThreadPriority);
+ except
+ // Some Android devices do not like this
+ end;
+end;
+
+destructor TncCustomUDPServer.Destroy;
+begin
+ Active := False;
+
+ LineProcessor.Terminate;
+ LineProcessor.WakeupEvent.SetEvent;
+ LineProcessor.WaitFor;
+ LineProcessor.Free;
+
+ Line.Free;
+
+ inherited Destroy;
+end;
+
+function TncCustomUDPServer.GetLine: TncLine;
+begin
+ Result := Line;
+end;
+
+function TncCustomUDPServer.GetActive: Boolean;
+begin
+ Result := Line.Active;
+end;
+
+procedure TncCustomUDPServer.DoActivate(aActivate: Boolean);
+begin
+ if aActivate = GetActive then
+ Exit;
+
+ if aActivate then
+ begin
+
+ // Verify family setting before creating handle
+ if Line.Family <> FFamily then
+ begin
+ TncLineInternal(Line).SetFamily(FFamily);
+ end;
+
+ // CreateServerHandle will bind to all interfaces (0.0.0.0)
+ // through the AI_PASSIVE flag in ncLines.CreateServerHandle
+ TncLineInternal(Line).CreateServerHandle(FPort);
+
+ // Enable broadcast if needed
+ if Broadcast then
+ TncLineInternal(Line).EnableBroadcast;
+
+ // Set socket buffer sizes for better performance
+ try
+ TncLineInternal(Line).SetReceiveSize(ReadBufferLen);
+ TncLineInternal(Line).SetWriteSize(ReadBufferLen);
+ except
+ // Ignore buffer size errors
+ end;
+
+ SetLength(ReadSocketHandles, 1);
+ ReadSocketHandles[0] := Line.Handle;
+
+ if UseReaderThread then
+ begin
+ LineProcessor.WaitForReady;
+ LineProcessor.Run;
+ end;
+ end
+ else
+ begin
+ TncLineInternal(Line).DestroyHandle;
+ SetLength(ReadSocketHandles, 0);
+ end;
+end;
+
+// 1. Base SendTo that does the actual sending
+procedure TncCustomUDPServer.SendTo(const aBuf; aBufSize: Integer; const DestAddr: TSockAddrStorage);
+var
+ AddrLen: Integer;
+ {$IFDEF MSWINDOWS}
+ BytesSent: Integer;
+ {$ELSE}
+ BytesSent: ssize_t;
+ {$ENDIF}
+ DestIP: string;
+begin
+ if not Active then
+ raise EPropertySetError.Create(ECannotSendWhileSocketInactiveStr);
+ try
+ // Get destination address for logging/error reporting
+ DestIP := TncIPUtils.GetIPFromStorage(DestAddr);
+ // Set proper address length based on family
+ case DestAddr.ss_family of
+ AF_INET: AddrLen := SizeOf(TSockAddr);
+ AF_INET6: AddrLen := SizeOf(TSockAddrIn6);
+ else
+ AddrLen := SizeOf(TSockAddrStorage);
+ end;
+ {$IFDEF MSWINDOWS}
+ BytesSent := Winapi.Winsock2.sendto(Line.Handle, aBuf, aBufSize, 0,
+ Psockaddr(@DestAddr), AddrLen);
+ if BytesSent = SOCKET_ERROR then
+ raise Exception.CreateFmt('Failed to send to %s: %s',
+ [DestIP, SysErrorMessage(WSAGetLastError)]);
+ {$ELSE}
+ BytesSent := Posix.SysSocket.sendto(Line.Handle, @aBuf, aBufSize, 0,
+ Psockaddr(@DestAddr), AddrLen);
+ if BytesSent < 0 then
+ raise Exception.CreateFmt('Failed to send to %s: %s',
+ [DestIP, SysErrorMessage(GetLastError)]);
+ {$ENDIF}
+ except
+ on E: EIPError do
+ raise Exception.Create('Invalid destination address: ' + E.Message);
+ end;
+end;
+
+// 2. SendTo for byte arrays
+procedure TncCustomUDPServer.SendTo(const aBytes: TBytes; const DestAddr: TSockAddrStorage);
+begin
+ if Length(aBytes) > 0 then
+ SendTo(aBytes[0], Length(aBytes), DestAddr);
+end;
+
+// 3. SendTo for strings
+procedure TncCustomUDPServer.SendTo(const aStr: string; const DestAddr: TSockAddrStorage);
+var
+ bytes: TBytes;
+ len: Integer;
+begin
+ bytes := BytesOf(aStr);
+ len := Length(bytes);
+ if len > 0 then
+ SendTo(bytes[0], len, DestAddr);
+end;
+
+function TncCustomUDPServer.Receive(aTimeout: Cardinal = 2000): TBytes;
+var
+ BufRead: Integer;
+ SenderAddr: TSockAddrStorage;
+ SenderAddrLen: Integer;
+ SenderIP: string;
+begin
+ if UseReaderThread then
+ raise Exception.Create(ECannotReceiveIfUseReaderThreadStr);
+
+ Active := True;
+
+ if not ReadableAnySocket([Line.Handle], aTimeout) then
+ begin
+ SetLength(Result, 0);
+ Exit;
+ end;
+
+ SenderAddrLen := SizeOf(TSockAddrStorage);
+ FillChar(SenderAddr, SenderAddrLen, 0);
+
+ BufRead := recvfrom(Line.Handle, ReadBuf[0], Length(ReadBuf), 0,
+ PSockAddr(@SenderAddr)^, SenderAddrLen);
+
+ try
+ if BufRead > 0 then
+ begin
+ // Get sender IP for logging if needed
+ SenderIP := TncIPUtils.GetIPFromStorage(SenderAddr);
+ Result := Copy(ReadBuf, 0, BufRead);
+ end
+ else if BufRead = 0 then
+ begin
+ SetLength(Result, 0);
+ // Optional: raise Exception.Create('Connection closed by peer');
+ end
+ else
+ begin
+ SetLength(Result, 0);
+ {$IFDEF MSWINDOWS}
+ raise Exception.Create('Receive error: ' + SysErrorMessage(WSAGetLastError));
+ {$ELSE}
+ raise Exception.Create('Receive error: ' + SysErrorMessage(GetLastError));
+ {$ENDIF}
+ end;
+ except
+ on E: EIPError do
+ begin
+ SetLength(Result, 0);
+ raise Exception.Create('Invalid sender address: ' + E.Message);
+ end;
+ end;
+end;
+
+{ TncUDPServerProcessor }
+
+constructor TncUDPServerProcessor.Create(aServerSocket: TncCustomUDPServer);
+begin
+ FServerSocket := aServerSocket;
+ ReadySocketsChanged := False;
+ inherited Create;
+end;
+
+
+procedure TncUDPServerProcessor.ProcessDatagram;
+var
+ BufRead: Integer;
+ SenderAddr: TSockAddrStorage;
+ SenderAddrLen: Integer;
+begin
+ SenderAddrLen := SizeOf(TSockAddrStorage);
+ FillChar(SenderAddr, SenderAddrLen, 0);
+
+ BufRead := recvfrom(FServerSocket.Line.Handle,
+ FServerSocket.ReadBuf[0],
+ Length(FServerSocket.ReadBuf),
+ 0,
+ PSockAddr(@SenderAddr)^,
+ SenderAddrLen);
+
+ if (BufRead > 0) and Assigned(FServerSocket.OnReadDatagram) then
+ try
+ FServerSocket.OnReadDatagram(FServerSocket, FServerSocket.Line,
+ FServerSocket.ReadBuf, BufRead, SenderAddr);
+ except
+ end;
+end;
+
+procedure TncUDPServerProcessor.ProcessEvent;
+begin
+ if FServerSocket.EventsUseMainThread then
+ while FServerSocket.Active and (not Terminated) do
+ try
+ if ReadableAnySocket(FServerSocket.ReadSocketHandles, 500) then
+ begin
+ if ReadySocketsChanged then
+ begin
+ ReadySocketsChanged := False;
+ Continue;
+ end;
+ Synchronize(ProcessDatagram);
+ end;
+ except
+ end
+ else
+ while FServerSocket.Active and (not Terminated) do
+ try
+ if ReadableAnySocket(FServerSocket.ReadSocketHandles, 500) then
+ begin
+ if ReadySocketsChanged then
+ begin
+ ReadySocketsChanged := False;
+ Continue;
+ end;
+ ProcessDatagram;
+ end;
+ except
+ end;
+end;
+
+end.
+
diff --git a/image-1.png b/image-1.png
new file mode 100644
index 0000000..70d5a94
Binary files /dev/null and b/image-1.png differ
diff --git a/image-2.png b/image-2.png
new file mode 100644
index 0000000..b320654
Binary files /dev/null and b/image-2.png differ