comp.lang.ada
 help / color / mirror / Atom feed
From: Craig Carey <research@ijs.co.nz>
Subject: Re: GNAT.Sockets Problems
Date: Sun, 11 May 2003 12:51:42 +1200
Date: 2003-05-11T12:51:42+12:00	[thread overview]
Message-ID: <1n3rbv0ljgvg3eluo4rl3irflkno54oh32@4ax.com> (raw)
In-Reply-To: 28d8936a.0305091146.18a4dd57@posting.google.com



>ADA.IO_EXCEPTIONS.END_ERROR: s-stratt.adb:188

Here is file "s-stratt.adb:188" from the cvs site:

| package body System.Stream_Attributes is     * GNAT of "GCC 3.4" *
|    Err : exception renames Ada.IO_Exceptions.End_Error;
|    ...
|    function I_C (Stream : access RST) return Character is
|       T : S_C;
|       L : SEO;
|    begin
|       Ada.Streams.Read (Stream.all, T, L);
|       if L < T'Last then
L188>      raise Err;
|       else
|          return To_C (T);
|       end if;
|    end I_C;

I doubt that fast Ada programs handle data with a procedure call for each
byte.

I have some personal bindings to GNAT.Sockets here, in file "ptun1.adb":
http://www.ijs.co.nz/code/ada95_http_hdrs.zip (or of a similar name).

------------------------------------
Inset: * Browsing through the abuse officer's censoring proxy *:
 I released a TCP multiplexing proxy named (Ptunnel 2) that allows
 browsing through a censoring proxy. The proxy differs from HTTPort in
 that only 2 log file lines are left behind and it is in Ada and also
 the connections are out to port 80. Port 119 Usenet I/O can be downloaded
 through the proxy, and then all the messages are in a long "stream".
------------------------------------

The I_C() procedure is not something a fast well designed program would
need to contain. Ada's Streams are available and it seems very likely
that only Ada beginners use Streams for efficient code. There were about
passing binary data portably. However maybe outstanding programs convert
variant record data to ASCII text and then compress it. I don't know if
Streams are that essential. One thing that is missing from Ada is an
ability to read from the Standard Input and read directly into an array.

Back to Ada's streams. Strings can be used instead. I do't like I_C():

(1) I_C() reads character by character which is slower than it could be;

(2) I_C() raises exceptions. Some well running TCP programs have the
TCP connect fail often (e.g. 4 times a second). GDB can stop on all of
those exceptions.

Adasocket's TCP connect routine also raises exceptions so the package
is not a solution but it replicates the problem. Here is some of the
Adasockets code (from v1.6):

|   procedure Connect (Socket : in Socket_FD; Host : in String; Port ...
|   ...
|      if C_Connect (Socket.FD, Sin'Address, Sin'Size / 8) = Failure then
|         Current_Errno := Thin.Errno;
|         if Current_Errno = Constants.Econnrefused then
|            raise Connection_Refused;
|         else
|            Raise_With_Message
|              ("Connection failed (errno was" &
|               Integer'Image (Current_Errno) & ')',
|              False);

What would be faster than returning data Character by Character, is to
return the data in a string. Ada's Unbounded Strings is not a serious
option (since I have a faster "Seafood" fast strings package for use
with fast TCP proxies). But few know just how fast the secret Ada
string type is; i.e. the one that passes around strings explaining
exceptions. That unknown string type would be carrying away the Adasockets
error, "Connection failed...".

I had to write a lot of bindings to GNAT.Sockets. 


On 9 May 2003 12:46:48 -0700, file13@qlippoth.zzn.com (file13) wrote:

>Howdy all, I've been tinkering with GNAT.Sockets on Mandrake 9.1 using
>the Gnat-3.15p linux binary and I'm simply trying to write ...
...
>procedure Daytime_Client is
>   Target  : Inet_Addr_Type := Inet_Addr ("127.0.0.1");
>   Socket  : Socket_Type;
>   Server  : Sock_Addr_Type;
>   Channel : Stream_Access;
>begin
>   Initialize;
>   Create_Socket (Socket);
>   Server := (Family_Inet, Target, 13);
>   Connect_Socket (Socket, Server);
>   Channel := Stream (Socket, Server);
>   Put_Line (String'Input (Channel));
>   Shutdown_Socket (Socket);
>   Close_Socket (Socket);
>   Finalize;
...
>$ ./daytime_client
>ADA.IO_EXCEPTIONS.END_ERROR: s-stratt.adb:188
...
>http://www.qlippoth.com/ripban.py [...]
>file13: http://www.qlippoth.com/

Some of that Python code (immediately above) uses Unix signals to timeout
TCP connects. Maybe for Windows, a task would be used instead. Anyway,
signals can cause core dumps. This Python code attempts to kill anything
rather than just one socket:

|        except socket.error:
|            print "Connection refused"
|            sys.exit(1)
|        if os.name == "posix":
|            signal.signal(signal.SIGALRM, alarm_handler)
|            signal.alarm(timeout)
|        banner = sock.recv(1024)

I found that porting TCP code from Windows to Linux, can be slowed a
lot by these issues:
(1) tasks must be carefully unblocked by the program itself, and  Ctrl-C
  SIGTERM, and exit() (GNAT's OS_Exit()) can convert the Linux program
  into a zombie. Badbly designed Ada Linux programs may fail to close.
  It seems to be fixable (despite 1+ GNAT runtime bugs that show up only
  once the program has fully finished).
(2) SO_REUSEADDR needs to be handled correctly (Linux port numbers lock
 up).


Craig Carey








  reply	other threads:[~2003-05-11  0:51 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-05-09 19:46 GNAT.Sockets Problems file13
2003-05-11  0:51 ` Craig Carey [this message]
2003-05-12 11:38 ` Simon Clubley
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox