Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-04

socket timeout

10 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Xiangrong Fang

Hi there,

How can I set the connection and read/write timeout when using socket in free pascal? I like the way it works now (blocking, NOT async), but the timeout is a bit too long.

BTW, I hope the way to control timeout is withing the program and platform independent (instead of, e.g. set sysctrl under linux).

Thanks a lot.

Michael Schnell
to Xiangrong Fang
Xiangrong Fang wrote
How can I set the connection and read/write timeout when using socket in free pascal?

I seem to remember that synapse can do this.

-Michael

Mark Morgan Lloyd
to Michael Schnell
Michael Schnell wrote
On 04/16/2013 11:26 AM, Xiangrong Fang wrote: > How can I set the connection and read/write timeout when using socket > in free pascal? I seem to remember that synapse can do this.

Otherwise for non-standard protocols use fpconnect(), fpselect() etc.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Victor Campillo
to Xiangrong Fang: How can I set the connection and read/write timeout when using socket in free pascal? I…
Xiangrong Fang wrote 10 lines
Hi there, How can I set the connection and read/write timeout when using socket in free pascal? I like the way it works now (blocking, NOT async), but the timeout is a bit too long. BTW, I hope the way to control timeout is withing the program and platform independent (instead of, e.g. set sysctrl under linux). Thanks a lot.

Hi,

As you, when I work with sockets I like the blocking mode but the timeout of connect was a headache for me.

I use fpsetsockopt with the options SO_SNDTIMEO and SO_RCVTIMEO for the read/write timeout.

With connect I don't found an easy way to use my own timeout, so I made a little hack in this situation. At the same time that I call connect I start a new thread for registering the time pass, if the timeout is passed then close/shutdown the socket, this unblock the connect. In case that the connection was succesful then I terminate the parallel thread before it close the socket.

I don't like what I do for the timeout of connect but it's works, maybe this thread throw light in this issue and I can find a better way.

Best regards.

Victor Campillo
Luca Olivetti
to Michael Schnell: I seem to remember that synapse can do this. -Michael

Al 16/04/13 12:20, En/na Michael Schnell ha escrit:

On 04/16/2013 11:26 AM, Xiangrong Fang wrote: > How can I set the connection and read/write timeout when using socket > in free pascal? I seem to remember that synapse can do this.

Only in svn and it does it this way

if FConnectionTimeout > 0 then
begin
  // connect in non-blocking mode
  b := NonBlockMode;
  NonBlockMode := true;
  SockCheck(synsock.Connect(FSocket, Sin));
  if (FLastError = WSAEINPROGRESS) OR (FLastError = WSAEWOULDBLOCK) then
    if not CanWrite(FConnectionTimeout) then
      FLastError := WSAETIMEDOUT;
  NonBlockMode := b;
end
else
  SockCheck(synsock.Connect(FSocket, Sin));

NonBlockMode in turn uses fpIoCtl with the FIONBIO parameter, WSAEINPROGRESS=EsysEINPROGRESS, WSAEWOULDBLOCK=EsysEWOULDBLOCK and CanWrite does an fpSelect

Bye

Luca
Xiangrong Fang
to Luca Olivetti

Will this be a CPU hog:

t := Now;
while fprecv(s, @buf, buf_len, MSG_DONTWAIT) < 0 do begin
  if Now - t > 0.00001 * timeout then Break;   // approx. <timeout> seconds
end;

Thanks

2013/4/16 Luca Olivetti

Show quoted text 35 lines
Al 16/04/13 12:20, En/na Michael Schnell ha escrit: > On 04/16/2013 11:26 AM, Xiangrong Fang wrote: >> How can I set the connection and read/write timeout when using socket >> in free pascal? > I seem to remember that synapse can do this. Only in svn and it does it this way if FConnectionTimeout > 0 then begin // connect in non-blocking mode b := NonBlockMode; NonBlockMode := true; SockCheck(synsock.Connect(FSocket, Sin)); if (FLastError = WSAEINPROGRESS) OR (FLastError = WSAEWOULDBLOCK) then if not CanWrite(FConnectionTimeout) then FLastError := WSAETIMEDOUT; NonBlockMode := b; end else SockCheck(synsock.Connect(FSocket, Sin)); NonBlockMode in turn uses fpIoCtl with the FIONBIO parameter, WSAEINPROGRESS=EsysEINPROGRESS, WSAEWOULDBLOCK=EsysEWOULDBLOCK and CanWrite does an fpSelect Bye -- Luca _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Rainer Stratmann
to Xiangrong Fang
you wrote 8 lines
Will this be a CPU hog: t := Now; while fprecv(s, @buf, buf_len, MSG_DONTWAIT) < 0 do begin if Now - t > 0.00001 * timeout then Break; // approx. <timeout> seconds end; Thanks

I did not read the whole thread, but that you favorite blocking mode (which I don't use).

For MSG_DONTWAIT as far I know you have to change to the nonblocking mode.

Show quoted text 44 lines
2013/4/16 Luca Olivetti > Al 16/04/13 12:20, En/na Michael Schnell ha escrit: > > On 04/16/2013 11:26 AM, Xiangrong Fang wrote: > >> How can I set the connection and read/write timeout when using socket > >> in free pascal? > > > > I seem to remember that synapse can do this. > > Only in svn and it does it this way > > if FConnectionTimeout > 0 then > begin > > // connect in non-blocking mode > b := NonBlockMode; > NonBlockMode := true; > SockCheck(synsock.Connect(FSocket, Sin)); > if (FLastError = WSAEINPROGRESS) OR (FLastError = WSAEWOULDBLOCK) then > > if not CanWrite(FConnectionTimeout) then > > FLastError := WSAETIMEDOUT; > > NonBlockMode := b; > > end > else > > SockCheck(synsock.Connect(FSocket, Sin)); > > NonBlockMode in turn uses fpIoCtl with the FIONBIO parameter, > WSAEINPROGRESS=EsysEINPROGRESS, WSAEWOULDBLOCK=EsysEWOULDBLOCK and > CanWrite does an fpSelect > > Bye > -- > Luca > > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Xiangrong Fang
to Rainer Stratmann

I thought MSG_DONTWAIT is actually the flag to switch to nonblocking mode, isn't it? As a matter of fact, the fprecv() above would get a result of -1 and a sockterror of "Try Again", which is exactly the behavior of nonblocking read.

2013/4/17 Rainer Stratmann

Show quoted text 67 lines
On Wednesday 17 April 2013 09:17:09 you wrote: > Will this be a CPU hog: > > t := Now; > while fprecv(s, @buf, buf_len, MSG_DONTWAIT) < 0 do begin > if Now - t > 0.00001 * timeout then Break; // approx. <timeout> seconds > end; > > Thanks I did not read the whole thread, but that you favorite blocking mode (which I don't use). For MSG_DONTWAIT as far I know you have to change to the nonblocking mode. > > > 2013/4/16 Luca Olivetti > > > Al 16/04/13 12:20, En/na Michael Schnell ha escrit: > > > On 04/16/2013 11:26 AM, Xiangrong Fang wrote: > > >> How can I set the connection and read/write timeout when using socket > > >> in free pascal? > > > > > > I seem to remember that synapse can do this. > > > > Only in svn and it does it this way > > > > if FConnectionTimeout > 0 then > > begin > > > > // connect in non-blocking mode > > b := NonBlockMode; > > NonBlockMode := true; > > SockCheck(synsock.Connect(FSocket, Sin)); > > if (FLastError = WSAEINPROGRESS) OR (FLastError = WSAEWOULDBLOCK) then > > > > if not CanWrite(FConnectionTimeout) then > > > > FLastError := WSAETIMEDOUT; > > > > NonBlockMode := b; > > > > end > > else > > > > SockCheck(synsock.Connect(FSocket, Sin)); > > > > NonBlockMode in turn uses fpIoCtl with the FIONBIO parameter, > > WSAEINPROGRESS=EsysEINPROGRESS, WSAEWOULDBLOCK=EsysEWOULDBLOCK and > > CanWrite does an fpSelect > > > > Bye > > -- > > Luca > > > > _______________________________________________ > > fpc-pascal maillist - > > http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Rainer Stratmann
to Xiangrong Fang
you wrote
I thought MSG_DONTWAIT is actually the flag to switch to nonblocking mode, isn't it?

May be.

As a matter of fact, the fprecv() above would get a result of -1 and a sockterror of "Try Again", which is exactly the behavior of nonblocking read.

Yes it seems so.

I do always separately switch to the nonblocking mode before.

Show quoted text 76 lines
2013/4/17 Rainer Stratmann > On Wednesday 17 April 2013 09:17:09 you wrote: > > Will this be a CPU hog: > > > > t := Now; > > while fprecv(s, @buf, buf_len, MSG_DONTWAIT) < 0 do begin > > > > if Now - t > 0.00001 * timeout then Break; // approx. <timeout> > > seconds > > > end; > > > > Thanks > > I did not read the whole thread, but that you favorite blocking mode > (which I > don't use). > > For MSG_DONTWAIT as far I know you have to change to the nonblocking > mode. > > > 2013/4/16 Luca Olivetti > > > > > Al 16/04/13 12:20, En/na Michael Schnell ha escrit: > > > > On 04/16/2013 11:26 AM, Xiangrong Fang wrote: > > > >> How can I set the connection and read/write timeout when using > > socket > > > > >> in free pascal? > > > > > > > > I seem to remember that synapse can do this. > > > > > > Only in svn and it does it this way > > > > > > if FConnectionTimeout > 0 then > > > begin > > > > > > // connect in non-blocking mode > > > b := NonBlockMode; > > > NonBlockMode := true; > > > SockCheck(synsock.Connect(FSocket, Sin)); > > > if (FLastError = WSAEINPROGRESS) OR (FLastError = WSAEWOULDBLOCK) > > then > > > > if not CanWrite(FConnectionTimeout) then > > > > > > FLastError := WSAETIMEDOUT; > > > > > > NonBlockMode := b; > > > > > > end > > > else > > > > > > SockCheck(synsock.Connect(FSocket, Sin)); > > > > > > NonBlockMode in turn uses fpIoCtl with the FIONBIO parameter, > > > WSAEINPROGRESS=EsysEINPROGRESS, WSAEWOULDBLOCK=EsysEWOULDBLOCK and > > > CanWrite does an fpSelect > > > > > > Bye > > > -- > > > Luca > > > > > > _______________________________________________ > > > fpc-pascal maillist - > > > http://lists.freepascal.org/mailman/listinfo/fpc-pascal > > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Fabio Luis Girardi
to Rainer Stratmann

For connect, I wrote a unit that implements a connect timeout, see:

http://sourceforge.net/p/pascalscada/code/HEAD/tree/trunk/src/scada/sockets_w32_w64.pas#l70

or

http://sourceforge.net/p/pascalscada/code/HEAD/tree/trunk/src/scada/sockets_unix.pas#l48

If you want work in blocking mode after connect, do something like this:

fsocket = {$IFDEF WINDOWS}Socket{$ELSE}fpSocket{$ENDIF}(PF_INET, SOCK_STREAM, IPPROTO_TCP)

//set socket options.
setblockingmode(fsocket,MODE_NONBLOCKING);
if connect_with_timeout(focket,@channel,sizeof(channel),FTimeoutInMs)0
then begin
  //check errors
end;
setblockingmode(FSocket,MODE_BLOCKING);

2013/4/17 Rainer Stratmann :

Show quoted text 89 lines
On Wednesday 17 April 2013 10:22:58 you wrote: > I thought MSG_DONTWAIT is actually the flag to switch to nonblocking mode, > isn't it? May be. > As a matter of fact, the fprecv() above would get a result of -1 > and a sockterror of "Try Again", which is exactly the behavior of > nonblocking read. Yes it seems so. I do always separately switch to the nonblocking mode before. > > > 2013/4/17 Rainer Stratmann > > > On Wednesday 17 April 2013 09:17:09 you wrote: > > > Will this be a CPU hog: > > > > > > t := Now; > > > while fprecv(s, @buf, buf_len, MSG_DONTWAIT) < 0 do begin > > > > > > if Now - t > 0.00001 * timeout then Break; // approx. <timeout> > > > > seconds > > > > > end; > > > > > > Thanks > > > > I did not read the whole thread, but that you favorite blocking mode > > (which I > > don't use). > > > > For MSG_DONTWAIT as far I know you have to change to the nonblocking > > mode. > > > > > 2013/4/16 Luca Olivetti > > > > > > > Al 16/04/13 12:20, En/na Michael Schnell ha escrit: > > > > > On 04/16/2013 11:26 AM, Xiangrong Fang wrote: > > > > >> How can I set the connection and read/write timeout when using > > > > socket > > > > > > >> in free pascal? > > > > > > > > > > I seem to remember that synapse can do this. > > > > > > > > Only in svn and it does it this way > > > > > > > > if FConnectionTimeout > 0 then > > > > begin > > > > > > > > // connect in non-blocking mode > > > > b := NonBlockMode; > > > > NonBlockMode := true; > > > > SockCheck(synsock.Connect(FSocket, Sin)); > > > > if (FLastError = WSAEINPROGRESS) OR (FLastError = WSAEWOULDBLOCK) > > > > then > > > > > > if not CanWrite(FConnectionTimeout) then > > > > > > > > FLastError := WSAETIMEDOUT; > > > > > > > > NonBlockMode := b; > > > > > > > > end > > > > else > > > > > > > > SockCheck(synsock.Connect(FSocket, Sin)); > > > > > > > > NonBlockMode in turn uses fpIoCtl with the FIONBIO parameter, > > > > WSAEINPROGRESS=EsysEINPROGRESS, WSAEWOULDBLOCK=EsysEWOULDBLOCK and > > > > CanWrite does an fpSelect > > > > > > > > Bye > > > > -- > > > > Luca > > > > > > > > _______________________________________________ > > > > fpc-pascal maillist - > > > > http://lists.freepascal.org/mailman/listinfo/fpc-pascal > > > > _______________________________________________ > > fpc-pascal maillist - > > http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
The best regards, Fabio Luis Girardi PascalSCADA Project http://sourceforge.net/projects/pascalscada http://www.pascalscada.com