ESocketError with fphttpserver lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- FlKo · 2016-11-06 19:52 Hi there. In my "work life", beside VBS, LabVIEW and PLCs if required, I'm mostly a C++ programmer (for the major part with C++ Builder). As a "spare-time-approach", I'm trying my best to get into Object Pascal with Lazarus/Free Pascal because I'm used to the VCL from CBuilder and it never hurts learning another language. Now I'm trying to implement a simple webserver with Lazarus 1.6, FPC 3.0.0 and fphttpserver. I've created a form, put 2 buttons on it and copy-pasted the major part of the code from Michaël Van Canneyt's tutorial Creating a simple webserver in Lazarus. Everything works as expected, except for the server shutdown. When I click on 'Stop Server', the following exception is raised: Exception class "ESocketError" at $005415CA with message "Could not accept a client connection on socket: 584, error 10038 Stack trace is: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   FServer.Active := True (in procedure THTTPServerThread.Execute;)    procedure TFPCustomHttpServer.SetActive(const AValue: Boolean);      procedure TFPCustomHttpServer.StartServerSocket;        Procedure TSocketServer.StartAccepting;          Function TInetServer.GetConnection : TSocketStream;            Function TInetServer.Accept : Longint;              <-------- Error is raised here  And here is my code: frmmain.pas: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit frmmain; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,  httpserverthread, fphttpserver, fpweb, fpwebfile; type   { TMainForm }   TMainForm = class(TForm)    btnStart: TButton;    btnStop: TButton;    meLog: TMemo;    Panel1: TPanel;    procedure btnStopClick(Sender: TObject);    procedure btnStartClick(Sender: TObject);    procedure FormCreate(Sender: TObject);  private    FHandler: TFPCustomFileModule;    FURL: string;    FServer: THTTPServerThread;    procedure DoHandleRequest(Sender: TObject; var ARequest: TFPHTTPConnectionRequest;      var AResponse: TFPHTTPConnectionResponse);    procedure ShowURL;  public  end; var  MainForm: TMainForm; implementation {$R *.lfm} { TMainForm } procedure TMainForm.btnStartClick(Sender: TObject);begin  meLog.Lines.Add('Starting server');  FServer := THTTPServerThread.Create(8080, @DoHandleRequest);end; procedure TMainForm.FormCreate(Sender: TObject);begin  DoubleBuffered := true;   RegisterFileLocation('files', 'C:\Users\FlKo\Documents\lazarus\project \bin\i386-win32\debug\data\');  MimeTypesFile := 'C:\Users\FlKo\Docume nts\lazarus\project\bin\i386-win32\debug\etc\mime.types';  FHandler := TFPCustomFileModule.CreateNew(Self);  FHandler.BaseURL := 'files/';end; procedure TMainForm.btnStopClick(Sender: TObject);begin  meLog.Lines.Add('Stopping server');  FServer.DoTerminate;end; procedure TMainForm.DoHandleRequest(Sender: TObject;  var ARequest: TFPHTTPConnectionRequest; var AResponse: TFPHTTPConnectionResponse);begin  FURL := ARequest.URL;  FServer.Synchronize(FServer, @ShowURL);  FHandler.HandleRequest(ARequest, AResponse);end; procedure TMainForm.ShowURL;begin  meLog.Lines.Add('Handling request: ' + FURL);end; end.  httpserverthread.pas: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit HTTPServerThread; {$mode objfpc}{$H+} interface uses  Classes, SysUtils,  fphttpserver, fpweb, fpwebfile; type  THTTPServerThread = class(TThread)  private    FServer: TFPHTTPServer;  public    constructor Create(APort: word; const OnRequest: THTTPServerRequestHandler);    procedure Execute; override;    procedure DoTerminate; override;    property Server: TFPHTTPServer read FServer;  end;  implementation constructor THTTPServerThread.Create(APort: word; const OnRequest: THTTPServerRequestHandler);begin  inherited Create(False);  FServer := TFPHTTPServer.Create(nil);  FServer.Threaded:=true;  FServer.Port := APort;  FServer.OnRequest := OnRequest;end; procedure THTTPServerThread.Execute;begin  try    FServer.Active := True;  finally    FreeAndNil(FServer);  end;end; procedure THTTPServerThread.DoTerminate;begin  FServer.Active := False;  inherited DoTerminate;end; end.  Am I doing something wrong? Thanks for all answers. ---------------------------------------------------------------------- Leledumbo · 2016-11-07 00:08 10038 is socket error code for "Socket operation on nonsocket", i.e. the socket identifier is either not valid or no longer valid. You shouldn't call DoTerminate directly, but let thread class calls it after Execute terminates. You should expose something in the thread class that will set FServer.Active to false, but NOT in DoTerminate, and call it somewhere in frmmain. With your current code, DoTerminate will be called twice. The first one is your explicit call, the second one is after Execute. In the second call, FServer is no longer valid because finally block in Execute already FreeAndNil it. P.S.: DoTerminate is a protected method in FPC trunk, it really isn't meant to be called directly.