lnet.pp 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333
  1. { lNet v0.5.8
  2. CopyRight (C) 2004-2007 Ales Katona
  3. This library is Free software; you can rediStribute it and/or modify it
  4. under the terms of the GNU Library General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or (at your
  6. option) any later version.
  7. This program is diStributed in the hope that it will be useful, but WITHOUT
  8. ANY WARRANTY; withOut even the implied warranty of MERCHANTABILITY or
  9. FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
  10. for more details.
  11. You should have received a Copy of the GNU Library General Public License
  12. along with This library; if not, Write to the Free Software Foundation,
  13. Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. This license has been modified. See File LICENSE.ADDON for more inFormation.
  15. Should you find these sources without a LICENSE File, please contact
  16. me at [email protected]
  17. }
  18. unit lNet;
  19. {$mode objfpc}{$H+}{$T-}
  20. {$interfaces corba}
  21. interface
  22. uses
  23. Classes, lEvents,
  24. {$i sys/osunits.inc}
  25. const
  26. { Address constants }
  27. LADDR_ANY = '0.0.0.0';
  28. LADDR_BR = '255.255.255.255';
  29. LADDR_LO = '127.0.0.1';
  30. { ICMP }
  31. LICMP_ECHOREPLY = 0;
  32. LICMP_UNREACH = 3;
  33. LICMP_ECHO = 8;
  34. LICMP_TIME_EXCEEDED = 11;
  35. { Protocols }
  36. LPROTO_IP = 0;
  37. LPROTO_ICMP = 1;
  38. LPROTO_IGMP = 2;
  39. LPROTO_TCP = 6;
  40. LPROTO_UDP = 17;
  41. LPROTO_IPV6 = 41;
  42. LPROTO_ICMPV6 = 58;
  43. LPROTO_RAW = 255;
  44. LPROTO_MAX = 256;
  45. type
  46. PLIPHeader = ^TLIPHeader;
  47. TLIPHeader = record
  48. VerLen : Byte;
  49. TOS : Byte;
  50. TotalLen : Word;
  51. Identifer : Word;
  52. FragOffsets : Word;
  53. TTL : Byte;
  54. Protocol : Byte;
  55. CheckSum : Word;
  56. SourceIp : DWord;
  57. DestIp : DWord;
  58. Options : DWord;
  59. end; // TLIPHeader
  60. TLSocket = class;
  61. TLComponent = class;
  62. { Callback Event procedure for errors }
  63. TLSocketErrorEvent = procedure(const msg: string; aSocket: TLSocket) of object;
  64. { Callback Event procedure for others }
  65. TLSocketEvent = procedure(aSocket: TLSocket) of object;
  66. { Callback Event procedure for progress reports}
  67. TLSocketProgressEvent = procedure (aSocket: TLSocket; const Bytes: Integer) of object;
  68. { Base socket class, Holds Address and socket info, perForms basic
  69. socket operations, uses select always to figure out if it can work (slow) }
  70. { TLSocket }
  71. TLSocket = class(TLHandle)
  72. protected
  73. FAddress: TInetSockAddr;
  74. FPeerAddress: TInetSockAddr;
  75. FReuseAddress: Boolean;
  76. FConnected: Boolean;
  77. FConnecting: Boolean;
  78. FNextSock: TLSocket;
  79. FPrevSock: TLSocket;
  80. FIgnoreShutdown: Boolean;
  81. FCanSend: Boolean;
  82. FCanReceive: Boolean;
  83. FServerSocket: Boolean;
  84. FOnFree: TLSocketEvent;
  85. FBlocking: Boolean;
  86. FListenBacklog: Integer;
  87. FProtocol: Integer;
  88. FSocketType: Integer;
  89. FCreator: TLComponent;
  90. protected
  91. function DoSend(const TheData; const TheSize: Integer): Integer;
  92. function SetupSocket(const APort: Word; const Address: string): Boolean; virtual;
  93. function GetLocalPort: Word;
  94. function GetPeerPort: Word;
  95. function GetPeerAddress: string;
  96. function GetLocalAddress: string;
  97. function CanSend: Boolean; virtual;
  98. function CanReceive: Boolean; virtual;
  99. procedure SetOptions; virtual;
  100. procedure SetBlocking(const aValue: Boolean);
  101. procedure SetReuseAddress(const aValue: Boolean);
  102. function Bail(const msg: string; const ernum: Integer): Boolean;
  103. procedure LogError(const msg: string; const ernum: Integer); virtual;
  104. public
  105. constructor Create; override;
  106. destructor Destroy; override;
  107. function Listen(const APort: Word; const AIntf: string = LADDR_ANY): Boolean;
  108. function Accept(const SerSock: Integer): Boolean;
  109. function Connect(const Address: string; const APort: Word): Boolean;
  110. function Send(const aData; const aSize: Integer): Integer; virtual;
  111. function SendMessage(const msg: string): Integer;
  112. function Get(var aData; const aSize: Integer): Integer; virtual;
  113. function GetMessage(out msg: string): Integer;
  114. procedure Disconnect; virtual;
  115. public
  116. property Connected: Boolean read FConnected;
  117. property Connecting: Boolean read FConnecting;
  118. property Blocking: Boolean read FBlocking write SetBlocking;
  119. property ListenBacklog: Integer read FListenBacklog write FListenBacklog;
  120. property Protocol: Integer read FProtocol write FProtocol;
  121. property SocketType: Integer read FSocketType write FSocketType;
  122. property PeerAddress: string read GetPeerAddress;
  123. property PeerPort: Word read GetPeerPort;
  124. property LocalAddress: string read GetLocalAddress;
  125. property LocalPort: Word read GetLocalPort;
  126. property ReuseAddress: Boolean read FReuseAddress write SetReuseAddress;
  127. property NextSock: TLSocket read FNextSock write FNextSock;
  128. property PrevSock: TLSocket read FPrevSock write FPrevSock;
  129. property Creator: TLComponent read FCreator;
  130. end;
  131. TLSocketClass = class of TLSocket;
  132. { this is the socket used by TLConnection }
  133. TLActionEnum = (acConnect, acAccept, acSend, acReceive, acError);
  134. { Base interface common to ALL connections }
  135. ILComponent = interface
  136. procedure Disconnect;
  137. procedure CallAction;
  138. property SocketClass: TLSocketClass;
  139. property Host: string;
  140. property Port: Word;
  141. end;
  142. { Interface for protools with direct send/get capabilities }
  143. ILDirect = interface
  144. function Get(var aData; const aSize: Integer; aSocket: TLSocket = nil): Integer;
  145. function GetMessage(out msg: string; aSocket: TLSocket = nil): Integer;
  146. function Send(const aData; const aSize: Integer; aSocket: TLSocket = nil): Integer;
  147. function SendMessage(const msg: string; aSocket: TLSocket = nil): Integer;
  148. end;
  149. { Interface for all servers }
  150. ILServer = interface
  151. function Listen(const APort: Word; const AIntf: string = LADDR_ANY): Boolean;
  152. end;
  153. { Interface for all clients }
  154. ILClient = interface
  155. function Connect(const Address: string; const APort: Word): Boolean; overload;
  156. function Connect: Boolean; overload;
  157. end;
  158. { TLComponent }
  159. TLComponent = class(TComponent, ILComponent)
  160. protected
  161. FHost: string;
  162. FPort: Word;
  163. FCreator: TLComponent;
  164. public
  165. constructor Create(aOwner: TComponent); override;
  166. procedure Disconnect; virtual; abstract;
  167. procedure CallAction; virtual; abstract;
  168. public
  169. SocketClass: TLSocketClass;
  170. property Host: string read FHost write FHost;
  171. property Port: Word read FPort write FPort;
  172. property Creator: TLComponent read FCreator write FCreator;
  173. end;
  174. { TLConnection
  175. Common ancestor for TLBaseTcp and TLUdp classes. Holds Event properties
  176. and common variables. }
  177. TLConnection = class(TLComponent, ILDirect, ILServer, ILClient)
  178. protected
  179. FTimeVal: TTimeVal;
  180. FOnReceive: TLSocketEvent;
  181. FOnAccept: TLSocketEvent;
  182. FOnConnect: TLSocketEvent;
  183. FOnDisconnect: TLSocketEvent;
  184. FOnCanSend: TLSocketEvent;
  185. FOnError: TLSocketErrorEvent;
  186. FRootSock: TLSocket;
  187. FIterator: TLSocket;
  188. FID: Integer; // internal number for server
  189. FEventer: TLEventer;
  190. FEventerClass: TLEventerClass;
  191. FTimeout: Integer;
  192. FListenBacklog: Integer;
  193. protected
  194. function InitSocket(aSocket: TLSocket): TLSocket; virtual;
  195. function GetConnected: Boolean; virtual; abstract;
  196. function GetCount: Integer; virtual;
  197. function GetItem(const i: Integer): TLSocket;
  198. function GetTimeout: Integer;
  199. procedure SetTimeout(const AValue: Integer);
  200. procedure SetEventer(Value: TLEventer);
  201. procedure ConnectAction(aSocket: TLHandle); virtual;
  202. procedure AcceptAction(aSocket: TLHandle); virtual;
  203. procedure ReceiveAction(aSocket: TLHandle); virtual;
  204. procedure SendAction(aSocket: TLHandle); virtual;
  205. procedure ErrorAction(aSocket: TLHandle; const msg: string); virtual;
  206. procedure ConnectEvent(aSocket: TLHandle); virtual;
  207. procedure DisconnectEvent(aSocket: TLHandle); virtual;
  208. procedure AcceptEvent(aSocket: TLHandle); virtual;
  209. procedure ReceiveEvent(aSocket: TLHandle); virtual;
  210. procedure CanSendEvent(aSocket: TLHandle); virtual;
  211. procedure ErrorEvent(const msg: string; aSocket: TLHandle); virtual;
  212. procedure EventerError(const msg: string; Sender: TLEventer);
  213. procedure RegisterWithEventer; virtual;
  214. procedure FreeSocks; virtual;
  215. public
  216. constructor Create(aOwner: TComponent); override;
  217. destructor Destroy; override;
  218. function Connect(const Address: string; const APort: Word): Boolean; virtual; overload;
  219. function Connect: Boolean; virtual; overload;
  220. function Listen(const APort: Word; const AIntf: string = LADDR_ANY): Boolean; virtual; abstract; overload;
  221. function Listen: Boolean; virtual; overload;
  222. function Get(var aData; const aSize: Integer; aSocket: TLSocket = nil): Integer; virtual; abstract;
  223. function GetMessage(out msg: string; aSocket: TLSocket = nil): Integer; virtual; abstract;
  224. function Send(const aData; const aSize: Integer; aSocket: TLSocket = nil): Integer; virtual; abstract;
  225. function SendMessage(const msg: string; aSocket: TLSocket = nil): Integer; virtual; abstract;
  226. function IterNext: Boolean; virtual; abstract;
  227. procedure IterReset; virtual; abstract;
  228. public
  229. property OnError: TLSocketErrorEvent read FOnError write FOnError;
  230. property OnReceive: TLSocketEvent read FOnReceive write FOnReceive;
  231. property OnDisconnect: TLSocketEvent read FOnDisconnect write FOnDisconnect;
  232. property OnCanSend: TLSocketEvent read FOnCanSend write FOnCanSend;
  233. property Socks[index: Integer]: TLSocket read GetItem; default;
  234. property Count: Integer read GetCount;
  235. property Connected: Boolean read GetConnected;
  236. property ListenBacklog: Integer read FListenBacklog write FListenBacklog;
  237. property Iterator: TLSocket read FIterator;
  238. property Timeout: Integer read GetTimeout write SetTimeout;
  239. property Eventer: TLEventer read FEventer write SetEventer;
  240. property EventerClass: TLEventerClass read FEventerClass write FEventerClass;
  241. end;
  242. { UDP Client/Server class. Provided to enable usage of UDP sockets }
  243. { TLUdp }
  244. TLUdp = class(TLConnection)
  245. protected
  246. function InitSocket(aSocket: TLSocket): TLSocket; override;
  247. function GetConnected: Boolean; override;
  248. procedure ReceiveAction(aSocket: TLHandle); override;
  249. procedure SendAction(aSocket: TLHandle); override;
  250. procedure ErrorAction(aSocket: TLHandle; const msg: string); override;
  251. function Bail(const msg: string): Boolean;
  252. procedure SetAddress(const Address: string);
  253. public
  254. constructor Create(aOwner: TComponent); override;
  255. function Connect(const Address: string; const APort: Word): Boolean; override;
  256. function Listen(const APort: Word; const AIntf: string = LADDR_ANY): Boolean; override;
  257. function Get(var aData; const aSize: Integer; aSocket: TLSocket = nil): Integer; override;
  258. function GetMessage(out msg: string; aSocket: TLSocket = nil): Integer; override;
  259. function SendMessage(const msg: string; aSocket: TLSocket = nil): Integer; override;
  260. function SendMessage(const msg: string; const Address: string): Integer; overload;
  261. function Send(const aData; const aSize: Integer; aSocket: TLSocket = nil): Integer; override;
  262. function Send(const aData; const aSize: Integer; const Address: string): Integer; overload;
  263. function IterNext: Boolean; override;
  264. procedure IterReset; override;
  265. procedure Disconnect; override;
  266. procedure CallAction; override;
  267. end;
  268. { TCP Client/Server class. Provided to enable usage of TCP sockets }
  269. { TLTcp }
  270. TLTcp = class(TLConnection)
  271. protected
  272. FCount: Integer;
  273. FReuseAddress: Boolean;
  274. function InitSocket(aSocket: TLSocket): TLSocket; override;
  275. function GetConnected: Boolean; override;
  276. function GetConnecting: Boolean;
  277. function GetCount: Integer; override;
  278. procedure SetReuseAddress(const aValue: Boolean);
  279. procedure ConnectAction(aSocket: TLHandle); override;
  280. procedure AcceptAction(aSocket: TLHandle); override;
  281. procedure ReceiveAction(aSocket: TLHandle); override;
  282. procedure SendAction(aSocket: TLHandle); override;
  283. procedure ErrorAction(aSocket: TLHandle; const msg: string); override;
  284. function Bail(const msg: string; aSocket: TLSocket): Boolean;
  285. procedure SocketDisconnect(aSocket: TLSocket);
  286. public
  287. constructor Create(aOwner: TComponent); override;
  288. function Connect(const Address: string; const APort: Word): Boolean; override;
  289. function Listen(const APort: Word; const AIntf: string = LADDR_ANY): Boolean; override;
  290. function Get(var aData; const aSize: Integer; aSocket: TLSocket = nil): Integer; override;
  291. function GetMessage(out msg: string; aSocket: TLSocket = nil): Integer; override;
  292. function Send(const aData; const aSize: Integer; aSocket: TLSocket = nil): Integer; override;
  293. function SendMessage(const msg: string; aSocket: TLSocket = nil): Integer; override;
  294. function IterNext: Boolean; override;
  295. procedure IterReset; override;
  296. procedure CallAction; override;
  297. procedure Disconnect; override;
  298. public
  299. property Connecting: Boolean read GetConnecting;
  300. property OnAccept: TLSocketEvent read FOnAccept write FOnAccept;
  301. property OnConnect: TLSocketEvent read FOnConnect write FOnConnect;
  302. property ReuseAddress: Boolean read FReuseAddress write SetReuseAddress;
  303. end;
  304. implementation
  305. uses
  306. lCommon;
  307. //********************************TLSocket*************************************
  308. constructor TLSocket.Create;
  309. begin
  310. inherited Create;
  311. FHandle := INVALID_SOCKET;
  312. FBlocking := False;
  313. FListenBacklog := LDEFAULT_BACKLOG;
  314. FServerSocket := False;
  315. FPrevSock := nil;
  316. FNextSock := nil;
  317. FCanSend := True;
  318. FCanReceive := False;
  319. FConnected := False;
  320. FConnecting := False;
  321. FIgnoreShutdown := False;
  322. FSocketType := SOCK_STREAM;
  323. FProtocol := LPROTO_TCP;
  324. end;
  325. destructor TLSocket.Destroy;
  326. begin
  327. if Assigned(FOnFree) then
  328. FOnFree(Self);
  329. inherited Destroy; // important! must be called before disconnect
  330. Disconnect;
  331. end;
  332. procedure TLSocket.Disconnect;
  333. var
  334. WasConnected: Boolean;
  335. begin
  336. WasConnected := FConnected;
  337. FDispose := True;
  338. FCanSend := True;
  339. FCanReceive := True;
  340. FIgnoreWrite := True;
  341. if FConnected or FConnecting then begin
  342. FConnected := False;
  343. FConnecting := False;
  344. if (FSocketType = SOCK_STREAM) and (not FIgnoreShutdown) and WasConnected then
  345. if fpShutDown(FHandle, 2) <> 0 then
  346. LogError('Shutdown error', LSocketError);
  347. if Assigned(FEventer) then
  348. FEventer.UnregisterHandle(Self);
  349. if CloseSocket(FHandle) <> 0 then
  350. LogError('Closesocket error', LSocketError);
  351. FHandle := INVALID_SOCKET;
  352. end;
  353. end;
  354. procedure TLSocket.LogError(const msg: string; const ernum: Integer);
  355. begin
  356. if Assigned(FOnError) then
  357. if ernum > 0 then
  358. FOnError(Self, msg + LStrError(ernum))
  359. else
  360. FOnError(Self, msg);
  361. end;
  362. function TLSocket.Bail(const msg: string; const ernum: Integer): Boolean;
  363. begin
  364. Result := False; // return the result for the caller
  365. Disconnect;
  366. LogError(msg, ernum);
  367. end;
  368. function TLSocket.GetPeerAddress: string;
  369. begin
  370. Result := '';
  371. if FSocketType = SOCK_STREAM then
  372. Result := NetAddrtoStr(FAddress.Addr)
  373. else
  374. Result := NetAddrtoStr(FPeerAddress.Addr);
  375. end;
  376. function TLSocket.GetLocalAddress: string;
  377. var
  378. a: TSockAddr;
  379. l: Integer;
  380. begin
  381. Result := '';
  382. l := SizeOf(a);
  383. if fpGetSockName(FHandle, @a, @l) = 0 then
  384. Result := NetAddrToStr(LongWord(a.sin_addr));
  385. end;
  386. function TLSocket.CanSend: Boolean;
  387. begin
  388. Result := FCanSend and FConnected;
  389. end;
  390. function TLSocket.CanReceive: Boolean;
  391. begin
  392. Result := FCanReceive and FConnected;
  393. end;
  394. procedure TLSocket.SetOptions;
  395. begin
  396. SetBlocking(FBlocking);
  397. end;
  398. procedure TLSocket.SetBlocking(const aValue: Boolean);
  399. begin
  400. FBlocking := aValue;
  401. if FHandle >= 0 then // we already set our socket
  402. if not lCommon.SetBlocking(FHandle, aValue) then
  403. Bail('Error on SetBlocking', LSocketError);
  404. end;
  405. procedure TLSocket.SetReuseAddress(const aValue: Boolean);
  406. begin
  407. if not FConnected then
  408. FReuseAddress := aValue;
  409. end;
  410. function TLSocket.GetMessage(out msg: string): Integer;
  411. begin
  412. Result := 0;
  413. SetLength(msg, BUFFER_SIZE);
  414. SetLength(msg, Get(PChar(msg)^, Length(msg)));
  415. Result := Length(msg);
  416. end;
  417. function TLSocket.Get(var aData; const aSize: Integer): Integer;
  418. var
  419. AddressLength: Integer = SizeOf(FPeerAddress);
  420. LastError: Longint;
  421. begin
  422. Result := 0;
  423. if CanReceive then begin
  424. if FSocketType = SOCK_STREAM then
  425. Result := sockets.fpRecv(FHandle, @aData, aSize, LMSG)
  426. else
  427. Result := sockets.fpRecvfrom(FHandle, @aData, aSize, LMSG, @FPeerAddress, @AddressLength);
  428. if Result = 0 then
  429. if FSocketType = SOCK_STREAM then
  430. Disconnect
  431. else
  432. Bail('Receive Error [0 on recvfrom with UDP]', 0);
  433. if Result = SOCKET_ERROR then begin
  434. LastError := LSocketError;
  435. if IsBlockError(LastError) then begin
  436. FCanReceive := False;
  437. IgnoreRead := False;
  438. end else
  439. Bail('Receive Error', LastError);
  440. Result := 0;
  441. end;
  442. end;
  443. end;
  444. function TLSocket.DoSend(const TheData; const TheSize: Integer): Integer;
  445. var
  446. AddressLength: Integer;
  447. begin
  448. AddressLength := SizeOf(FPeerAddress);
  449. if FSocketType = SOCK_STREAM then
  450. Result := sockets.fpsend(FHandle, @TheData, TheSize, LMSG)
  451. else
  452. Result := sockets.fpsendto(FHandle, @TheData, TheSize, LMSG, @FPeerAddress, AddressLength);
  453. end;
  454. function TLSocket.SetupSocket(const APort: Word; const Address: string): Boolean;
  455. var
  456. Done: Boolean;
  457. Arg, Opt: Integer;
  458. begin
  459. Result := false;
  460. if not FConnected and not FConnecting then begin
  461. Done := true;
  462. FHandle := fpSocket(AF_INET, FSocketType, FProtocol);
  463. if FHandle = INVALID_SOCKET then
  464. Exit(Bail('Socket error', LSocketError));
  465. SetOptions;
  466. Arg := 1;
  467. if FSocketType = SOCK_DGRAM then begin
  468. if fpsetsockopt(FHandle, SOL_SOCKET, SO_BROADCAST, @Arg, Sizeof(Arg)) = SOCKET_ERROR then
  469. Exit(Bail('SetSockOpt error', LSocketError));
  470. end else if FReuseAddress then begin
  471. Opt := SO_REUSEADDR;
  472. {$ifdef WIN32} // I expect 64 has it oddly, so screw them for now
  473. if (Win32Platform = 2) and (Win32MajorVersion >= 5) then
  474. Opt := Integer(not Opt);
  475. {$endif}
  476. if fpsetsockopt(FHandle, SOL_SOCKET, Opt, @Arg, Sizeof(Arg)) = SOCKET_ERROR then
  477. Exit(Bail('SetSockOpt error', LSocketError));
  478. end;
  479. {$ifdef darwin}
  480. Arg := 1;
  481. if fpsetsockopt(FHandle, SOL_SOCKET, SO_NOSIGPIPE, @Arg, Sizeof(Arg)) = SOCKET_ERROR then
  482. Exit(Bail('SetSockOpt error', LSocketError));
  483. {$endif}
  484. FillAddressInfo(FAddress, AF_INET, Address, aPort);
  485. FillAddressInfo(FPeerAddress, AF_INET, LADDR_BR, aPort);
  486. Result := Done;
  487. end;
  488. end;
  489. function TLSocket.GetLocalPort: Word;
  490. begin
  491. Result := ntohs(FAddress.sin_port);
  492. end;
  493. function TLSocket.GetPeerPort: Word;
  494. begin
  495. Result := ntohs(FPeerAddress.sin_port);
  496. end;
  497. function TLSocket.Listen(const APort: Word; const AIntf: string = LADDR_ANY): Boolean;
  498. begin
  499. if not Connected then begin
  500. Result := false;
  501. SetupSocket(APort, AIntf);
  502. if fpBind(FHandle, psockaddr(@FAddress), SizeOf(FAddress)) = SOCKET_ERROR then
  503. Bail('Error on bind', LSocketError)
  504. else
  505. Result := true;
  506. if (FSocketType = SOCK_STREAM) and Result then
  507. if fpListen(FHandle, FListenBacklog) = SOCKET_ERROR then
  508. Result := Bail('Error on Listen', LSocketError)
  509. else
  510. Result := true;
  511. end;
  512. end;
  513. function TLSocket.Accept(const sersock: Integer): Boolean;
  514. var
  515. AddressLength: tsocklen = SizeOf(FAddress);
  516. begin
  517. Result := false;
  518. if not Connected then begin
  519. FHandle := fpAccept(sersock, psockaddr(@FAddress), @AddressLength);
  520. if FHandle <> INVALID_SOCKET then begin
  521. SetOptions;
  522. Result := true;
  523. FConnected := true;
  524. end else
  525. Bail('Error on accept', LSocketError);
  526. end;
  527. end;
  528. function TLSocket.Connect(const Address: string; const aPort: Word): Boolean;
  529. begin
  530. Result := False;
  531. if Connected or FConnecting then
  532. Disconnect;
  533. if SetupSocket(APort, Address) then begin
  534. fpConnect(FHandle, psockaddr(@FAddress), SizeOf(FAddress));
  535. FConnecting := True;
  536. Result := FConnecting;
  537. end;
  538. end;
  539. function TLSocket.SendMessage(const msg: string): Integer;
  540. begin
  541. Result := Send(PChar(msg)^, Length(msg));
  542. end;
  543. function TLSocket.Send(const aData; const aSize: Integer): Integer;
  544. var
  545. LastError: Longint;
  546. begin
  547. Result := 0;
  548. if not FServerSocket then begin
  549. if aSize <= 0 then begin
  550. Bail('Send error: wrong size (Size <= 0)', -1);
  551. Exit(0);
  552. end;
  553. if CanSend then begin
  554. Result := DoSend(aData, aSize);
  555. if Result = SOCKET_ERROR then begin
  556. LastError := LSocketError;
  557. if IsBlockError(LastError) then begin
  558. FCanSend := False;
  559. IgnoreWrite := False;
  560. end else
  561. Bail('Send error', LastError);
  562. Result := 0;
  563. end;
  564. end;
  565. end;
  566. end;
  567. //*******************************TLConnection*********************************
  568. constructor TLConnection.Create(aOwner: TComponent);
  569. begin
  570. inherited Create(aOwner);
  571. FHost := '';
  572. FPort := 0;
  573. FListenBacklog := LDEFAULT_BACKLOG;
  574. FTimeout := 0;
  575. SocketClass := TLSocket;
  576. FOnReceive := nil;
  577. FOnError := nil;
  578. FOnDisconnect := nil;
  579. FOnCanSend := nil;
  580. FOnConnect := nil;
  581. FOnAccept := nil;
  582. FTimeVal.tv_sec := 0;
  583. FTimeVal.tv_usec := 0;
  584. FIterator := nil;
  585. FEventer := nil;
  586. FEventerClass := BestEventerClass;
  587. end;
  588. destructor TLConnection.Destroy;
  589. begin
  590. FreeSocks;
  591. if Assigned(FEventer) then
  592. FEventer.DeleteRef;
  593. inherited Destroy;
  594. end;
  595. function TLConnection.Connect(const Address: string; const APort: Word
  596. ): Boolean;
  597. begin
  598. FHost := Address;
  599. FPort := aPort;
  600. Result := False;
  601. end;
  602. function TLConnection.Connect: Boolean;
  603. begin
  604. Result := Connect(FHost, FPort);
  605. end;
  606. function TLConnection.Listen: Boolean;
  607. begin
  608. Result := Listen(FPort, FHost);
  609. end;
  610. function TLConnection.InitSocket(aSocket: TLSocket): TLSocket;
  611. begin
  612. aSocket.OnRead := @ReceiveAction;
  613. aSocket.OnWrite := @SendAction;
  614. aSocket.OnError := @ErrorAction;
  615. aSocket.ListenBacklog := FListenBacklog;
  616. aSocket.FCreator := FCreator;
  617. Result := aSocket;
  618. end;
  619. function TLConnection.GetCount: Integer;
  620. begin
  621. Result := 1;
  622. end;
  623. function TLConnection.GetItem(const i: Integer): TLSocket;
  624. var
  625. Tmp: TLSocket;
  626. Jumps: Integer;
  627. begin
  628. Result := nil;
  629. Tmp := FRootSock;
  630. Jumps := 0;
  631. while Assigned(Tmp.NextSock) and (Jumps < i) do begin
  632. Tmp := Tmp.NextSock;
  633. Inc(Jumps);
  634. end;
  635. if Jumps = i then
  636. Result := Tmp;
  637. end;
  638. function TLConnection.GetTimeout: Integer;
  639. begin
  640. if Assigned(FEventer) then
  641. Result := FEventer.Timeout
  642. else
  643. Result := FTimeout;
  644. end;
  645. procedure TLConnection.ConnectAction(aSocket: TLHandle);
  646. begin
  647. end;
  648. procedure TLConnection.AcceptAction(aSocket: TLHandle);
  649. begin
  650. end;
  651. procedure TLConnection.ReceiveAction(aSocket: TLHandle);
  652. begin
  653. end;
  654. procedure TLConnection.SendAction(aSocket: TLHandle);
  655. begin
  656. end;
  657. procedure TLConnection.ErrorAction(aSocket: TLHandle; const msg: string);
  658. begin
  659. end;
  660. procedure TLConnection.ConnectEvent(aSocket: TLHandle);
  661. begin
  662. if Assigned(FOnConnect) then
  663. FOnConnect(TLSocket(aSocket));
  664. end;
  665. procedure TLConnection.DisconnectEvent(aSocket: TLHandle);
  666. begin
  667. if Assigned(FOnDisconnect) then
  668. FOnDisconnect(TLSocket(aSocket));
  669. end;
  670. procedure TLConnection.AcceptEvent(aSocket: TLHandle);
  671. begin
  672. if Assigned(FOnAccept) then
  673. FOnAccept(TLSocket(aSocket));
  674. end;
  675. procedure TLConnection.ReceiveEvent(aSocket: TLHandle);
  676. begin
  677. if Assigned(FOnReceive) then
  678. FOnReceive(TLSocket(aSocket));
  679. end;
  680. procedure TLConnection.CanSendEvent(aSocket: TLHandle);
  681. begin
  682. if Assigned(FOnCanSend) then
  683. FOnCanSend(TLSocket(aSocket));
  684. end;
  685. procedure TLConnection.ErrorEvent(const msg: string; aSocket: TLHandle);
  686. begin
  687. if Assigned(FOnError) then
  688. FOnError(msg, TLSocket(aSocket));
  689. end;
  690. procedure TLConnection.SetTimeout(const AValue: Integer);
  691. begin
  692. if Assigned(FEventer) then
  693. FEventer.Timeout := aValue;
  694. FTimeout := aValue;
  695. end;
  696. procedure TLConnection.SetEventer(Value: TLEventer);
  697. begin
  698. if Assigned(FEventer) then
  699. FEventer.DeleteRef;
  700. FEventer := Value;
  701. FEventer.AddRef;
  702. end;
  703. procedure TLConnection.EventerError(const msg: string; Sender: TLEventer);
  704. begin
  705. ErrorEvent(msg, nil);
  706. end;
  707. procedure TLConnection.RegisterWithEventer;
  708. begin
  709. if not Assigned(FEventer) then begin
  710. FEventer := FEventerClass.Create;
  711. FEventer.OnError := @EventerError;
  712. end;
  713. if Assigned(FRootSock) then
  714. FEventer.AddHandle(FRootSock);
  715. if (FEventer.Timeout = 0) and (FTimeout <> 0) then
  716. FEventer.Timeout := FTimeout
  717. else
  718. FTimeout := FEventer.Timeout;
  719. end;
  720. procedure TLConnection.FreeSocks;
  721. var
  722. Tmp, Tmp2: TLSocket;
  723. begin
  724. Tmp := FRootSock;
  725. while Assigned(Tmp) do begin
  726. Tmp2 := Tmp;
  727. Tmp := Tmp.NextSock;
  728. Tmp2.Disconnect;
  729. Tmp2.Free;
  730. end;
  731. end;
  732. //*******************************TLUdp*********************************
  733. constructor TLUdp.Create(aOwner: TComponent);
  734. begin
  735. inherited Create(aOwner);
  736. FTimeVal.tv_usec := 0;
  737. FTimeVal.tv_sec := 0;
  738. end;
  739. procedure TLUdp.Disconnect;
  740. begin
  741. if Assigned(FRootSock) then begin
  742. FRootSock.Disconnect;
  743. FRootSock := nil; // even if the old one exists, eventer takes care of it
  744. end;
  745. end;
  746. function TLUdp.Connect(const Address: string; const APort: Word): Boolean;
  747. begin
  748. Result := inherited Connect(Address, aPort);
  749. if Assigned(FRootSock) and FRootSock.Connected then
  750. Disconnect;
  751. FRootSock := InitSocket(SocketClass.Create);
  752. FIterator := FRootSock;
  753. Result := FRootSock.SetupSocket(APort, LADDR_ANY);
  754. if Result then begin
  755. FillAddressInfo(FRootSock.FPeerAddress, AF_INET, Address, aPort);
  756. FRootSock.FConnected := true;
  757. RegisterWithEventer;
  758. end;
  759. end;
  760. function TLUdp.Listen(const APort: Word; const AIntf: string = LADDR_ANY): Boolean;
  761. begin
  762. Result := False;
  763. if Assigned(FRootSock) and FRootSock.Connected then
  764. Disconnect;
  765. FRootSock := InitSocket(SocketClass.Create);
  766. FIterator := FRootSock;
  767. if FRootSock.Listen(APort, AIntf) then begin
  768. FillAddressInfo(FRootSock.FPeerAddress, AF_INET, LADDR_BR, aPort);
  769. FRootSock.FConnected := True;
  770. RegisterWithEventer;
  771. Result := True;
  772. end;
  773. end;
  774. function TLUdp.Bail(const msg: string): Boolean;
  775. begin
  776. Result := False;
  777. Disconnect;
  778. ErrorEvent(msg, FRootSock);
  779. end;
  780. procedure TLUdp.SetAddress(const Address: string);
  781. var
  782. n: Integer;
  783. s: string;
  784. p: Word;
  785. begin
  786. n := Pos(':', Address);
  787. if n > 0 then begin
  788. s := Copy(Address, 1, n-1);
  789. p := Word(StrToInt(Copy(Address, n+1, Length(Address))));
  790. FillAddressInfo(FRootSock.FPeerAddress, AF_INET, s, p);
  791. end else
  792. FillAddressInfo(FRootSock.FPeerAddress, AF_INET, Address,
  793. FRootSock.PeerPort);
  794. end;
  795. function TLUdp.InitSocket(aSocket: TLSocket): TLSocket;
  796. begin
  797. Result := FRootSock;
  798. if not Assigned(FRootSock) then begin
  799. Result := inherited InitSocket(aSocket);
  800. aSocket.SocketType := SOCK_DGRAM;
  801. aSocket.Protocol := LPROTO_UDP;
  802. end;
  803. end;
  804. procedure TLUdp.ReceiveAction(aSocket: TLHandle);
  805. begin
  806. with TLSocket(aSocket) do begin
  807. FCanReceive := True;
  808. ReceiveEvent(aSocket);
  809. end;
  810. end;
  811. procedure TLUdp.SendAction(aSocket: TLHandle);
  812. begin
  813. with TLSocket(aSocket) do begin
  814. FCanSend := True;
  815. IgnoreWrite := True;
  816. CanSendEvent(aSocket);
  817. end;
  818. end;
  819. procedure TLUdp.ErrorAction(aSocket: TLHandle; const msg: string);
  820. begin
  821. Bail(msg);
  822. end;
  823. function TLUdp.IterNext: Boolean;
  824. begin
  825. Result := False;
  826. end;
  827. procedure TLUdp.IterReset;
  828. begin
  829. end;
  830. procedure TLUdp.CallAction;
  831. begin
  832. if Assigned(FEventer) then
  833. FEventer.CallAction;
  834. end;
  835. function TLUdp.GetConnected: Boolean;
  836. begin
  837. Result := False;
  838. if Assigned(FRootSock) then
  839. Result := FRootSock.Connected;
  840. end;
  841. function TLUdp.Get(var aData; const aSize: Integer; aSocket: TLSocket): Integer;
  842. begin
  843. Result := 0;
  844. if Assigned(FRootSock) then
  845. Result := FRootSock.Get(aData, aSize);
  846. end;
  847. function TLUdp.GetMessage(out msg: string; aSocket: TLSocket): Integer;
  848. begin
  849. Result := 0;
  850. if Assigned(FRootSock) then
  851. Result := FRootSock.GetMessage(msg);
  852. end;
  853. function TLUdp.SendMessage(const msg: string; aSocket: TLSocket = nil): Integer;
  854. begin
  855. Result := 0;
  856. if Assigned(FRootSock) then
  857. Result := FRootSock.SendMessage(msg)
  858. end;
  859. function TLUdp.SendMessage(const msg: string; const Address: string): Integer;
  860. begin
  861. Result := 0;
  862. if Assigned(FRootSock) then begin
  863. SetAddress(Address);
  864. Result := FRootSock.SendMessage(msg)
  865. end;
  866. end;
  867. function TLUdp.Send(const aData; const aSize: Integer; aSocket: TLSocket): Integer;
  868. begin
  869. Result := 0;
  870. if Assigned(FRootSock) then
  871. Result := FRootSock.Send(aData, aSize)
  872. end;
  873. function TLUdp.Send(const aData; const aSize: Integer; const Address: string
  874. ): Integer;
  875. begin
  876. Result := 0;
  877. if Assigned(FRootSock) then begin
  878. SetAddress(Address);
  879. Result := FRootSock.Send(aData, aSize);
  880. end;
  881. end;
  882. //******************************TLTcp**********************************
  883. constructor TLTcp.Create(aOwner: TComponent);
  884. begin
  885. inherited Create(aOwner);
  886. FIterator := nil;
  887. FCount := 0;
  888. FRootSock := nil;
  889. end;
  890. function TLTcp.Connect(const Address: string; const APort: Word): Boolean;
  891. begin
  892. Result := inherited Connect(Address, aPort);
  893. if Assigned(FRootSock) then
  894. Disconnect;
  895. FRootSock := InitSocket(SocketClass.Create);
  896. Result := FRootSock.Connect(Address, aPort);
  897. if Result then begin
  898. Inc(FCount);
  899. FIterator := FRootSock;
  900. RegisterWithEventer;
  901. end else begin
  902. FreeAndNil(FRootSock); // one possible use, since we're not in eventer yet
  903. FIterator := nil;
  904. end;
  905. end;
  906. function TLTcp.Listen(const APort: Word; const AIntf: string = LADDR_ANY): Boolean;
  907. begin
  908. Result := false;
  909. if Assigned(FRootSock) then
  910. Disconnect;
  911. FRootSock := InitSocket(SocketClass.Create);
  912. FRootSock.FIgnoreShutdown := True;
  913. FRootSock.SetReuseAddress(FReuseAddress);
  914. if FRootSock.Listen(APort, AIntf) then begin
  915. FRootSock.FConnected := True;
  916. FRootSock.FServerSocket := True;
  917. FIterator := FRootSock;
  918. Inc(FCount);
  919. RegisterWithEventer;
  920. Result := true;
  921. end;
  922. end;
  923. function TLTcp.Bail(const msg: string; aSocket: TLSocket): Boolean;
  924. begin
  925. Result := False;
  926. ErrorEvent(msg, aSocket);
  927. if Assigned(aSocket) then
  928. aSocket.Disconnect
  929. else
  930. Disconnect;
  931. end;
  932. procedure TLTcp.SocketDisconnect(aSocket: TLSocket);
  933. begin
  934. if aSocket = FIterator then begin
  935. if Assigned(FIterator.NextSock) then
  936. FIterator := FIterator.NextSock
  937. else if Assigned(FIterator.PrevSock) then
  938. FIterator := FIterator.PrevSock
  939. else FIterator := nil; // NOT iterreset, not reorganized yet
  940. if Assigned(FIterator) and FIterator.FServerSocket then
  941. FIterator := nil;
  942. end;
  943. if aSocket = FRootSock then
  944. FRootSock := aSocket.NextSock;
  945. if Assigned(aSocket.PrevSock) then
  946. aSocket.PrevSock.NextSock := aSocket.NextSock;
  947. if Assigned(aSocket.NextSock) then
  948. aSocket.NextSock.PrevSock := aSocket.PrevSock;
  949. Dec(FCount);
  950. end;
  951. function TLTcp.InitSocket(aSocket: TLSocket): TLSocket;
  952. begin
  953. Result := inherited InitSocket(aSocket);
  954. aSocket.SocketType := SOCK_STREAM;
  955. aSocket.Protocol := LPROTO_TCP;
  956. aSocket.FOnFree := @SocketDisconnect;
  957. end;
  958. function TLTcp.IterNext: Boolean;
  959. begin
  960. Result := False;
  961. if Assigned(FIterator.NextSock) then begin
  962. FIterator := FIterator.NextSock;
  963. Result := True;
  964. end else IterReset;
  965. end;
  966. procedure TLTcp.IterReset;
  967. begin
  968. FIterator := FRootSock;
  969. end;
  970. procedure TLTcp.Disconnect;
  971. begin
  972. FreeSocks;
  973. FRootSock := nil;
  974. FCount := 0;
  975. FIterator := nil;
  976. end;
  977. procedure TLTcp.CallAction;
  978. begin
  979. if Assigned(FEventer) then
  980. FEventer.CallAction;
  981. end;
  982. procedure TLTcp.ConnectAction(aSocket: TLHandle);
  983. var
  984. a: TInetSockAddr;
  985. l: Longint;
  986. begin
  987. with TLSocket(aSocket) do begin
  988. l := SizeOf(a);
  989. if Sockets.fpGetPeerName(FHandle, @a, @l) <> 0 then
  990. Self.Bail('Error on connect: connection refused', TLSocket(aSocket))
  991. else begin
  992. FConnected := True;
  993. FConnecting := False;
  994. ConnectEvent(aSocket);
  995. end;
  996. end;
  997. end;
  998. procedure TLTcp.AcceptAction(aSocket: TLHandle);
  999. var
  1000. Tmp: TLSocket;
  1001. begin
  1002. Tmp := InitSocket(SocketClass.Create);
  1003. if Tmp.Accept(FRootSock.FHandle) then begin
  1004. if Assigned(FRootSock.FNextSock) then begin
  1005. Tmp.FNextSock := FRootSock.FNextSock;
  1006. FRootSock.FNextSock.FPrevSock := Tmp;
  1007. end;
  1008. FRootSock.FNextSock := Tmp;
  1009. Tmp.FPrevSock := FRootSock;
  1010. if not Assigned(FIterator) // if we don't have (bug?) an iterator yet
  1011. or FIterator.FServerSocket then // or if it's the first socket accepted
  1012. FIterator := Tmp; // assign it as iterator (don't assign later acceptees)
  1013. Inc(FCount);
  1014. FEventer.AddHandle(Tmp);
  1015. AcceptEvent(Tmp);
  1016. end else Tmp.Free;
  1017. end;
  1018. procedure TLTcp.ReceiveAction(aSocket: TLHandle);
  1019. begin
  1020. if (TLSocket(aSocket) = FRootSock) and TLSocket(aSocket).FServerSocket then
  1021. AcceptAction(aSocket)
  1022. else with TLSocket(aSocket) do begin
  1023. if Connected then begin
  1024. FCanReceive := True;
  1025. ReceiveEvent(aSocket);
  1026. if not Connected then begin
  1027. DisconnectEvent(aSocket);
  1028. aSocket.Free;
  1029. end;
  1030. end;
  1031. end;
  1032. end;
  1033. procedure TLTcp.SendAction(aSocket: TLHandle);
  1034. begin
  1035. with TLSocket(aSocket) do begin
  1036. if Connecting then
  1037. ConnectAction(aSocket);
  1038. FCanSend := True;
  1039. IgnoreWrite := True;
  1040. CanSendEvent(aSocket);
  1041. end;
  1042. end;
  1043. procedure TLTcp.ErrorAction(aSocket: TLHandle; const msg: string);
  1044. begin
  1045. with TLSocket(aSocket) do begin
  1046. if Connecting then
  1047. Self.Bail('Error on connect: connection refused' , TLSocket(aSocket))
  1048. else
  1049. Self.Bail(msg, TLSocket(aSocket));
  1050. end;
  1051. end;
  1052. function TLTcp.GetConnected: Boolean;
  1053. var
  1054. Tmp: TLSocket;
  1055. begin
  1056. Result := False;
  1057. Tmp := FRootSock;
  1058. while Assigned(Tmp) do begin
  1059. if Tmp.Connected then begin
  1060. Result := True;
  1061. Exit;
  1062. end else Tmp := Tmp.NextSock;
  1063. end;
  1064. end;
  1065. function TLTcp.GetConnecting: Boolean;
  1066. begin
  1067. Result := False;
  1068. if Assigned(FRootSock) then
  1069. Result := FRootSock.Connecting;
  1070. end;
  1071. function TLTcp.GetCount: Integer;
  1072. begin
  1073. Result := FCount;
  1074. end;
  1075. procedure TLTcp.SetReuseAddress(const aValue: Boolean);
  1076. begin
  1077. if not Assigned(FRootSock)
  1078. or not FRootSock.Connected then
  1079. FReuseAddress := aValue;
  1080. end;
  1081. function TLTcp.Get(var aData; const aSize: Integer; aSocket: TLSocket): Integer;
  1082. begin
  1083. Result := 0;
  1084. if not Assigned(aSocket) then
  1085. aSocket := FIterator;
  1086. if Assigned(aSocket) then
  1087. Result := aSocket.Get(aData, aSize);
  1088. end;
  1089. function TLTcp.GetMessage(out msg: string; aSocket: TLSocket): Integer;
  1090. begin
  1091. Result := 0;
  1092. if not Assigned(aSocket) then
  1093. aSocket := FIterator;
  1094. if Assigned(aSocket) then
  1095. Result := aSocket.GetMessage(msg);
  1096. end;
  1097. function TLTcp.Send(const aData; const aSize: Integer; aSocket: TLSocket): Integer;
  1098. begin
  1099. Result := 0;
  1100. if not Assigned(aSocket) then
  1101. aSocket := FIterator;
  1102. if Assigned(aSocket) and (aSize > 0) then
  1103. Result := aSocket.Send(aData, aSize);
  1104. end;
  1105. function TLTcp.SendMessage(const msg: string; aSocket: TLSocket): Integer;
  1106. begin
  1107. Result := Send(PChar(msg)^, Length(msg), aSocket);
  1108. end;
  1109. { TLComponent }
  1110. constructor TLComponent.Create(aOwner: TComponent);
  1111. begin
  1112. inherited Create(aOwner);
  1113. FCreator := Self;
  1114. end;
  1115. end.