Sign in Join

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

Mailing lists / fpc-pascal / 2008-07

SocketError

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

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

Carsten Bager

I have a simple TCP program and I want to see when the client breaks the line.
With the 205 compiler this is not a problem SocketError tells me, but with the 220 compiler nothing happens. Do I have to do something else?

When compiled to 386 SocketError always returns 0, but when compiled to ARM SocketError always returns 11.
Why the difference.

Carsten

--------------------------------------------
program tcp2ser;

{ A simple TCP program. }

uses
sockets, inetaux, myerror,
sysutils; {System}

const
   ListenPort : Word = 5000;
   MaxConn = 1;
var
   lSock, uSock : LongInt;
   sAddr : TInetSockAddr;
   Len : LongInt;
   c:char;
   WelcomeStranger:array[0..17] of char='Welcome, stranger!';
begin
   lSock := fpSocket(AF_INET,SOCK_STREAM,PF_UNSPEC);
   if lSock = -1 then SockError('Socket: ');
   with sAddr do
   begin
      Family := af_inet;
      Port := htons(ListenPort);
      Addr := 0;
   end;
   if fpBind(lSock, @sAddr, sizeof(sAddr))<0 then SockError('Bind: ');
   if fpListen(lSock, MaxConn)<0 then SockError('Listen: ');
   repeat
      Say('Waiting for connections...');
      Len := sizeof(sAddr);
      uSock := fpAccept(lSock, @sAddr, @Len);
      if uSock = -1 then SockError('Accept: ');
      Say('Accepted connection from ' + AddrToStr(sAddr.Addr));
      fpSend(uSock,@WelcomeStranger,18,MSG_DONTWAIT);
      repeat
        while FpRecv(uSock,@c,1,MSG_DONTWAIT) >0 do
        begin
          Writeln('-',c);
        end;
        sleep(1000);
        Writeln('->',SocketError);
      until c=chr(27);
      FpShutdown(uSock, 2);
      Say('Connection closed.');
   until False;
end.

Reply by email

Marco van de Voort
to Carsten Bager
Show quoted text 8 lines
I have a simple TCP program and I want to see when the client breaks the line. With the 205 compiler this is not a problem SocketError tells me, but with the 220 compiler nothing happens. Do I have to do something else? When compiled to 386 SocketError always returns 0, but when compiled to ARM SocketError always returns 11. Why the difference.

Ask your OS vendor. These are OS errors.

But:

11 is iirc EAGAIN, which means "try again", which is due to a potential deadlock in the kernel not being handled properly.

Reply by email

Carsten Bager
to Marco van de Voort
Ask your OS vendor. These are OS errors. But: 11 is iirc EAGAIN, which means "try again", which is due to a potential deadlock in the kernel not being handled properly.

You say that SocketErrors are OS errors but some influence the FPC compiler must have.
I modified my program a bit. It now works with the 222 compiler. but still not with the 220 compiler. That is because I get a SocketError 104 from the 222 compiled program, when sending to a broken connection. The 220 compiled program aborts without any warning when sending to a broken connection.
The FpRecv returns 0 when the connection is broken (and -1 when ok) when receive buffer is empty.
I cannot find this behavior documented anywhere.
So I am still locking for a reliable way to detect a broken connection.

-----------------------------------------------------------
program tcp2ser;

{ A simple TCP program. }

uses
sockets, inetaux, myerror,
sysutils; {System}

const
   ListenPort : Word = 5000;
   MaxConn = 1;
var
   lSock, uSock : LongInt;
   sAddr : TInetSockAddr;
   SocketError_,FpRecv_,Len : LongInt;
   c:char;
   WelcomeStranger:array[0..17] of char='Welcome, stranger!';
begin
   lSock := fpSocket(AF_INET,SOCK_STREAM,PF_UNSPEC);
   if lSock = -1 then SockError('Socket: ');
   with sAddr do
   begin
      Family := af_inet;
      Port := htons(ListenPort);
      Addr := 0;
   end;
   if fpBind(lSock, @sAddr, sizeof(sAddr))<0 then SockError('Bind: ');
   if fpListen(lSock, MaxConn)<0 then SockError('Listen: ');
   repeat
      Say('Waiting for connections...');
      Len := sizeof(sAddr);
      uSock := fpAccept(lSock, @sAddr, @Len);
      if uSock = -1 then SockError('Accept: ');
      Say('Accepted connection from ' + AddrToStr(sAddr.Addr));
      fpSend(uSock,@WelcomeStranger,18,MSG_DONTWAIT);
      repeat
        FpRecv_:=FpRecv(uSock,@c,1,MSG_DONTWAIT);
        while FpRecv_>0 do
        begin
          Writeln('-',c);
          FpRecv_:=FpRecv(uSock,@c,1,MSG_DONTWAIT);
        end;
        sleep(1000);
        if c='s' then fpSend(uSock,@WelcomeStranger,18,MSG_DONTWAIT);
        SocketError_:=SocketError;
        Writeln('->',SocketError_,FpRecv_:10);
      until (c=chr(27)) or ((SocketError_0) and ((SocketError_11))) or
(FpRecv_=0);
      FpShutdown(uSock, 2);
      Say('Connection closed.');
   until False;
end.

Med venlig hilsen
Carsten Bager

BEAS A/S
Brørupvænget 10
DK-7650 Bøvlingbjerg
Tlf. : +45 9788 5222 Fax : +45 9788 5434
www.beas.dk

Reply by email

Marco van de Voort
to Carsten Bager

[ Charset ISO-8859-1 unsupported, converting... ]

Show quoted text 7 lines
> Ask your OS vendor. These are OS errors. > But: > 11 is iirc EAGAIN, which means "try again", which is due to a potential > deadlock in the kernel not being handled properly. You say that SocketErrors are OS errors but some influence the FPC compiler must have.

You don't happen to fall for the trap where you use syscalls (e.g. a write) before you query the error ?

Try to rework you code as follows

if fpxxxx0 then
   begin
     aninteger:=fpgeterrno;
     writeln(aninteger);
   end;

and not

writeln(fpgeterrno); // the write prologue might destroy the contents.

Reply by email