comp.lang.ada
 help / color / mirror / Atom feed
From: Adrien Plisson <aplisson-news@stochastique.net>
Subject: Re: TCP/IP Sockets with GNAT.Sockets
Date: Mon, 02 May 2005 18:10:43 +0200
Date: 2005-05-02T18:10:43+02:00	[thread overview]
Message-ID: <42765108$0$22419$ba620e4c@news.skynet.be> (raw)
In-Reply-To: <1115045740.838321.306480@g14g2000cwa.googlegroups.com>

fabio de francesco wrote:
>>From my message: "...I am relying on comments in file g-socket.ads from
> GCC/GNAT sources...". Sorry for my poor English, I know that sometimes
> I'm unable to express clearly, but I had already done exactly what you
> now suggest.
[...]
> I also said I already know how to program with sockets in C.

i'm sorry if you misunderstood my words: i just wanted to make clear 
that you did exactly what you had to do, and that there was no other 
way to go.

>>the only big difference is in Streams, which is Ada specific...

(this was just an introduction for the next big paragraph...)(french 
style)

[...]
> Thank you for this detailed explanation.

you're welcome !

> This is exactly the problem that I have overcome with the help I've had
> from Eric Jacoboni. Both my client and server programs didn't work at
> exchanging messages with C programs. After searching the web I
> discovered I had to use Receive_Socket() and Send_Socket() in order to
> get over that problem.

that's plain wrong...

the problem is the use of attributes 'Output on arrays which output 
array bounds before array data. and since String is an array, 
String'Output outputs String bounds before string data. (in Ada you 
are no more in C: a string is not delimited by a null character but 
has a lower and an upper bound).

those bounds are always getting in the way when:
1. you are not aware of their existence on the stream
2. the reader of the stream is not an ada program.

anyway, you can get rid of those bounds by using 'Read and 'Write 
instead of 'Input and 'Output. BUT you have to know that using 'Read 
on unconstrained arrays (especially on String) is... well... A Bad 
Thing(tm). (i'm not even sure it works).

you should note that the problem is the same in C: when reading a 
string (sorry an array of char) from a socket, you don't know its 
length. how can you say you read the whole string, and not a sub-part, 
or worst, the whole string plus the beginning of the following data ?

if you can overcome this problem in C, rest assured you can overcome 
it in Ada...
(the exact default behavior for stream attributes is detailed in ARM95 
13.13.2: this includes the behavior for array bounds, type 
discriminants, tags...)

> S : String := "Hello";
> SEA : Stream_Element_Array(1..S'Length);
> for SEA'Address use S(S'First)'Address;
> Last : Stream_Element_Offset;
> Send_Socket( Socket, SEA, Last );

(i'm sorry i'm gonna be a bit rude) beuark !

this is implementation dependant:
- what if Character'Size /= Stream_Element'Size ?
- what if the memory organization of Stream_Element_Array does not 
match the one for a String ?
(i'm not sure overlays are not a recommended practice, but i may be wrong)

you'd better write this:

declare
     Socket : Socket_Type;
     Channel : Stream_Access;
begin
     -- open your socket here, then...
     Channel := Stream( Socket );

     String'Write( Channel, "Hello" );
     -- close your socket here...
end;


> This is not exactly what someone can find in a Python or C manual. :-)

i won't put it in an Ada manual either !!

> You're right about the fact that the fault is mine for not knowing
> Streams while a Socket package isn't required to give any explanations
> on the usage of a subject that is not so closely related.

it is not your fault, it is just that manuals/tutorials don't tell 
much about streams. and don't worry, it took me a long time to 
understand streams. i just don't want people to encounter the same 
problems i had with them, that's why i always try to "demystify" streams.

> Anyway the package authors cover about 350 lines with an procedure
> example only using Streams, without ever saying why and when you should
> sometimes choose Receive_Socket() and Send_Socket() in place of
> Streams.

maybe because you just don't need them ! or only need them when you 
plainly understand what's behind them.

> Thanks, it helped a lot to make me to understand Streams. I hope this
> time I have been able to make myself clear. 

you already made yourself clear...

-- 
rien



  reply	other threads:[~2005-05-02 16:10 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-05-02  2:42 TCP/IP Sockets with GNAT.Sockets fabio de francesco
2005-05-02  5:58 ` Eric Jacoboni
2005-05-02 12:11 ` Adrien Plisson
2005-05-02 14:55   ` fabio de francesco
2005-05-02 16:10     ` Adrien Plisson [this message]
2005-05-02 17:56       ` Eric Jacoboni
2005-05-02 18:30         ` Poul-Erik Andreasen
2005-05-02 19:10           ` Simon Wright
2005-05-03 13:00             ` Poul-Erik Andreasen
2005-05-03 21:48               ` Simon Wright
2005-05-04  8:01               ` Character'First, ASCII.NUL and others (Was: Re: TCP/IP Sockets with GNAT.Sockets) Adrien Plisson
2005-05-04 13:40                 ` Poul-Erik Andreasen
2005-05-02 20:37           ` TCP/IP Sockets with GNAT.Sockets fabio de francesco
2005-05-02 20:52             ` Adrien Plisson
2005-05-03 12:04               ` fabio de francesco
2005-05-03 12:22                 ` Adrien Plisson
2005-05-03 13:17             ` Poul-Erik Andreasen
2005-05-02 20:44         ` Adrien Plisson
2005-05-02 22:10           ` Eric Jacoboni
2005-05-02 23:42             ` tmoran
2005-05-02 19:39     ` Björn
2005-05-02 20:22       ` fabio de francesco
2005-05-09  4:03         ` Dave Thompson
replies disabled

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