IdSimpleServer.pas 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. { $HDR$}
  2. {**********************************************************************}
  3. { Unit archived using Team Coherence }
  4. { Team Coherence is Copyright 2002 by Quality Software Components }
  5. { }
  6. { For further information / comments, visit our WEB site at }
  7. { http://www.TeamCoherence.com }
  8. {**********************************************************************}
  9. {}
  10. { $Log: 10321: IdSimpleServer.pas
  11. {
  12. { Rev 1.2 7/13/04 6:14:58 PM RLebeau
  13. { Added support for BoundPortMin/Max propeties
  14. }
  15. {
  16. Rev 1.1 6/20/2003 7:47:46 PM BGooijen
  17. AcceptWait is now 1000 instead of 0 by default
  18. }
  19. {
  20. { Rev 1.0 2002.11.12 10:51:24 PM czhower
  21. }
  22. unit IdSimpleServer;
  23. interface
  24. uses
  25. Classes,
  26. IdSocketHandle, IdTCPConnection, IdStackConsts;
  27. const
  28. ID_ACCEPT_WAIT = 1000;
  29. type
  30. TIdSimpleServer = class(TIdTCPConnection)
  31. protected
  32. FAbortedRequested: Boolean;
  33. FAcceptWait: Integer;
  34. // FBinding: TIdSocketHandle;
  35. FBoundIP: String;
  36. FBoundPort: Integer;
  37. FBoundPortMin: Integer;
  38. FBoundPortMax: Integer;
  39. FListenHandle: TIdStackSocketHandle;
  40. FListening: Boolean;
  41. //
  42. function GetBinding: TIdSocketHandle;
  43. public
  44. procedure Abort; virtual;
  45. procedure BeginListen; virtual;
  46. procedure Bind; virtual;
  47. constructor Create(AOwner: TComponent); override;
  48. procedure CreateBinding;
  49. procedure EndListen; virtual;
  50. function Listen: Boolean; virtual;
  51. procedure ResetConnection; override;
  52. //
  53. property AcceptWait: integer read FAcceptWait write FAcceptWait default ID_ACCEPT_WAIT;
  54. property Binding: TIdSocketHandle read GetBinding;
  55. property ListenHandle: TIdStackSocketHandle read FListenHandle;
  56. published
  57. property BoundIP: string read FBoundIP write FBoundIP;
  58. property BoundPort: Integer read FBoundPort write FBoundPort;
  59. property BoundPortMin: Integer read FBoundPortMin write FBoundPortMin;
  60. property BoundPortMax: Integer read FBoundPortMax write FBoundPortMax;
  61. end;
  62. implementation
  63. uses
  64. IdGlobal, IdStack, IdIOHandlerSocket,
  65. SysUtils;
  66. { TIdSimpleServer }
  67. procedure TIdSimpleServer.Abort;
  68. begin
  69. FAbortedRequested := True;
  70. end;
  71. procedure TIdSimpleServer.BeginListen;
  72. begin
  73. // Must be before IOHandler as it resets it
  74. if not Assigned(Binding) then begin
  75. ResetConnection;
  76. CreateBinding;
  77. end;
  78. try
  79. if ListenHandle = Id_INVALID_SOCKET then begin
  80. Bind;
  81. end;
  82. Binding.Listen(15);
  83. FListening := True;
  84. except
  85. FreeAndNil(FIOHandler);
  86. raise;
  87. end;
  88. end;
  89. procedure TIdSimpleServer.Bind;
  90. begin
  91. with Binding do begin
  92. try
  93. AllocateSocket;
  94. FListenHandle := Handle;
  95. IP := BoundIP;
  96. Port := BoundPort;
  97. ClientPortMin := BoundPortMin;
  98. ClientPortMax := BoundPortMax;
  99. Bind;
  100. except
  101. FListenHandle := Id_INVALID_SOCKET;
  102. raise;
  103. end;
  104. end;
  105. end;
  106. constructor TIdSimpleServer.Create(AOwner: TComponent);
  107. begin
  108. inherited;
  109. FListenHandle := Id_INVALID_SOCKET;
  110. FAcceptWait := ID_ACCEPT_WAIT;
  111. end;
  112. procedure TIdSimpleServer.CreateBinding;
  113. begin
  114. IOHandler := TIdIOHandlerSocket.Create(Self);
  115. IOHandler.Open;
  116. end;
  117. procedure TIdSimpleServer.EndListen;
  118. begin
  119. ResetConnection;
  120. end;
  121. function TIdSimpleServer.GetBinding: TIdSocketHandle;
  122. begin
  123. if Assigned(IOHandler) then begin
  124. Result := TIdIOHandlerSocket(IOHandler).Binding;
  125. end else begin
  126. Result := nil;
  127. end;
  128. end;
  129. function TIdSimpleServer.Listen: Boolean;
  130. begin
  131. //TODO: Add a timeout to this function.
  132. Result := False;
  133. if not FListening then begin
  134. BeginListen;
  135. end;
  136. with Binding do begin
  137. if FAbortedRequested = False then
  138. begin
  139. while (FAbortedRequested = False) and (Result = False) do begin
  140. Result := Readable(AcceptWait);
  141. end;
  142. end;
  143. if Result then begin
  144. Binding.Listen(1);
  145. Binding.Accept(binding.Handle);
  146. end;
  147. GStack.WSCloseSocket(ListenHandle);
  148. FListenHandle := Id_INVALID_SOCKET;
  149. end;
  150. end;
  151. procedure TIdSimpleServer.ResetConnection;
  152. begin
  153. inherited ResetConnection;
  154. FAbortedRequested := False;
  155. FListening := False;
  156. FreeAndNil(FIOHandler);
  157. end;
  158. end.