EldoS | Feel safer!

Software components for data protection, secure storage and transfer

TElSocket Send Timeout

Also by EldoS: CallbackDisk
Create virtual disks backed by memory or custom location, expose disk images as disks and more.
#29225
Posted: 04/11/2014 10:07:21
by Darian Miller (Standard support level)
Joined: 06/27/2011
Posts: 48

Delphi XE5/64-bit. When using TElSocket - what's the preferred way of setting a timeout on a Send method? Do I use SetSockOpt(NativeSocket, SO_SNDTIMEO, xx) .. directly?

I'm trying to chase down a stuck server and I have timeouts on connections and on some custom read routines, but don't see anything on Sends.
#29226
Posted: 04/11/2014 10:17:01
by Vsevolod Ievgiienko (EldoS Corp.)

Thank you for contacting us.

You can use TElSocket.CanSend method before Send is called to check if data can be sent.

As you have the source code, I recommend you to refer to TElCustomSimpleSSLClient.DoSend from SBSimpleSSL.pas for correct send with timeout implementation.
#29228
Posted: 04/11/2014 10:59:35
by Darian Miller (Standard support level)
Joined: 06/27/2011
Posts: 48

I'll take a look thanks, would suggest a simple SendWithTimeout() method added to TElSocket. (And a ReceiveWithTimeout)
#29229
Posted: 04/11/2014 11:38:26
by Eugene Mayevski (EldoS Corp.)

Well, that's exactly what CanSend and CanReceive do. I am not sure that we must bloat the API with the function which contains just one line of code, eg. if CanSend(timeout) then result := Send(...);


Sincerely yours
Eugene Mayevski
#29230
Posted: 04/11/2014 11:38:31
by Darian Miller (Standard support level)
Joined: 06/27/2011
Posts: 48

Ok - quick SocketHelper added for .SendWithTimeout that worked the first time tested. :)

Thanks


Code
  TElSocketHelper = class helper for TElSocket
  public
    function SendWithTimeout(const pBuffer:Pointer; const pSize:Integer; var pBytesSent:Integer; const pSendTimeoutMS:Integer):Integer;
  end;

const
  HELPER_READ_TIMEOUT = -2;
  HELPER_READ_ABORTED = -3;
  HELPER_LOST_CONNECTION = -4;
---


function TElSocketHelper.SendWithTimeout(const pBuffer:Pointer; const pSize:Integer; var pBytesSent:Integer; const pSendTimeoutMS:Integer):Integer;
var
  ToSend, Sent:Integer;
begin
  Result := 0;

  pBytesSent := 0;
  Sent := 0;
  ToSend := pSize;

  while (Result = 0) and (ToSend > 0) do
  begin
    try
      if State <> issConnected then
      begin
        Close(True);
        Result := HELPER_LOST_CONNECTION;
        Break;
      end;

      if pSendTimeoutMS > 0 then
      begin
        if not CanSend(pSendTimeoutMS) then
        begin
          Result := HELPER_READ_TIMEOUT;
          Break;
        end;
      end;

      Result := Send(Pointer(PtrUInt(pBuffer) + Cardinal(pSize - ToSend)), ToSend, Sent);
      if Result <> 0 then
      begin
        Result := HELPER_LOST_CONNECTION;
        Break;
      end;
      Dec(ToSend, Sent);
      Inc(pBytesSent, Sent);
    except
      on E : EElSocketError do
      begin
        Close(True);
        Result := HELPER_LOST_CONNECTION;
        Break;
      end;
    end;
  end;
end;
#29231
Posted: 04/11/2014 11:41:03
by Darian Miller (Standard support level)
Joined: 06/27/2011
Posts: 48

As far as a one-liner..

If CanSend(timeout) succeeds will .Send(data, BytesToSend, BytesSent) always send full BytesToSend?
#29232
Posted: 04/11/2014 11:49:34
by Eugene Mayevski (EldoS Corp.)

No, CanSend signals only that there's some available space in the outgoing buffers. Send() can always send less than you requested. Higher-level components such as TElSimpleSSLClient (which you can use in Passthrough mode BTW) handle this situation internally by calling Send in a loop.


Sincerely yours
Eugene Mayevski
#29233
Posted: 04/11/2014 12:22:49
by Darian Miller (Standard support level)
Joined: 06/27/2011
Posts: 48

Then a simple one-liner wouldn't suffice in this case. So I repeat my suggestion for a SendWithTimeout method. I've implemented a Class Helper to satisfy the needs at this point.
#29234
Posted: 04/11/2014 12:27:34
by Eugene Mayevski (EldoS Corp.)

And I suggest using TElSimpleSSLClient in this case :).


Sincerely yours
Eugene Mayevski
Also by EldoS: MsgConnect
Cross-platform protocol-independent communication framework for building peer-to-peer and client-server applications and middleware components.

Reply

Statistics

Topic viewed 900 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!