Lazarus

Programming => Networking and Web Programming => Topic started by: snorkel on December 13, 2019, 04:58:49 pm

Title: Indy 10 TCPServer listener error: Error on call to Winsock2 library function WSA
Post by: snorkel on December 13, 2019, 04:58:49 pm
Hi,
Using the build of indy in the package manager and I noticed that when I call myIdtcpServer.active:=false it has been raising this error in the Listener error event:
Server listener exception: Error on call to Winsock2 library function WSAGetLastError: Either the application has not called WSAStartup, or WSAStartup failed.

Using latest Lazarus IDE on windows 10.

Anyone else see this and maybe have a solution?
Title: Re: Indy 10 TCPServer listener error: Error on call to Winsock2 library function WSA
Post by: Remy Lebeau on December 13, 2019, 10:34:05 pm
Using the build of indy in the package manager and I noticed that when I call myIdtcpServer.active:=false it has been raising this error in the Listener error event:
Server listener exception: Error on call to Winsock2 library function WSAGetLastError: Either the application has not called WSAStartup, or WSAStartup failed.

You are going to have to provide a reproducible example.  Simply (de)activating the server does not call WSAStartup()/WSACleanup().  The ONLY way that EXACT error message can occur is when Indy's IdWinsock2.Stub_WSAGetLastError() function is called at runtime and the Winsock DLL is not currently loaded in memory by Indy (the IdWinsock2.WinsockHandle() function returns 0 and the IdWinsock2.Winsock2Loaded() function returns False).

Code: [Select]
function FixupStub(hDll: TIdLibHandle; const AName:{$IFDEF WINCE}TIdUnicodeString{$ELSE}string{$ENDIF}): Pointer;
{$IFDEF USE_INLINE}inline;{$ENDIF}
begin
  if hDll = IdNilHandle then begin
    raise EIdWinsockStubError.Build(WSANOTINITIALISED, RSWinsockCallError, [AName]); // <-- ERROR RAISED HERE!!!
  end;
  Result := Windows.GetProcAddress(hDll, {$IFDEF WINCE}PWideChar{$ELSE}PChar{$ENDIF}(AName));
  if Result = nil then begin
    raise EIdWinsockStubError.Build(WSAEINVAL, RSWinsockCallError, [AName]);
  end;
end;

function Stub_WSAGetLastError: Integer; stdcall;
begin
  @WSAGetLastError := FixupStub(hWinSockDll, 'WSAGetLastError'); {Do not Localize} // <-- ONLY IF hWinSockDll IS 0!!!
  Result := WSAGetLastError;
end;

That can only happen if the following conditions are met:


So, it sounds like maybe something in your project is causing Indy to unload Winsock before the server has been deactivated.  Try putting a breakpoint on Indy's IdWinsock2.UninitializeWinSock() function and see if it is getting called while your server is active, and if so then look at the call stack to find out why it is being called.