From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,7db5fb0599fd4b76 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!news.glorb.com!feeder.xsnews.nl!feeder.news-service.com!skynet.be!skynet.be!newspost001!tjb!not-for-mail Date: Mon, 02 May 2005 22:44:22 +0200 From: Adrien Plisson Reply-To: aplisson-news@stochastique.net User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax) X-Accept-Language: fr-be, fr, en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: TCP/IP Sockets with GNAT.Sockets References: <1115001752.291144.218410@z14g2000cwz.googlegroups.com> <427618e9$0$7743$ba620e4c@news.skynet.be> <1115045740.838321.306480@g14g2000cwa.googlegroups.com> <42765108$0$22419$ba620e4c@news.skynet.be> <020520051956181888%jaco@neottia.net> In-Reply-To: <020520051956181888%jaco@neottia.net> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Message-ID: <42769099$0$24172$ba620e4c@news.skynet.be> Organization: -= Belgacom Usenet Service =- NNTP-Posting-Host: 5a8cc02c.news.skynet.be X-Trace: 1115066522 news.skynet.be 24172 81.240.43.208:11420 X-Complaints-To: usenet-abuse@skynet.be Xref: g2news1.google.com comp.lang.ada:10886 Date: 2005-05-02T22:44:22+02:00 List-Id: Eric Jacoboni wrote: >>(i'm sorry i'm gonna be a bit rude) beuark ! > > Agree. It's not the sort of things i expected to write with Ada... But, > that's the only code that fits my needs. i would rather say: that's the only way you found to fit your need. remember the old Perl adage: there is more than one way to do it ! >>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 ? > > For the second point, Stream_Element_Array is defined as an array of > Stream_Element, so i suppose it match the memory organization of a > String, isn't it ? Stream_Element_Array matches the organization of an array, BUT: - Stream_Element is implementation defined (see ARM95 13.13.1), and this does not guarantee Stream_Element'Size = Character'Size (unless i missed something). strangely, it is 8 bits wide on every platform i used, but i would not bet on it for "exotic" 36 bit platforms for example... - Stream_Element_Array may, for efficiency reason, use a different convention than String, which would render them incompatible. (pragma Convention( C, Stream_Element_Array) for example) - the original code was: for SEA'Address use S(S'First)'Address; which places SEA at the address of the first component of S. this is different from: for SEA'Address use S'Address; however, i'm not fond of overlay, so don't ask me to explain why it is this way... > Have you tried this code with a server not Ada aware? Have you tried to > exchange messages with, say, a POP3 server? (to send and to read) I've > tried to use Streams for that, but i never succeeded to make it work... > If a cleaner solution exists, why the hell cannot we find _any_ > example? this is my Ada client: ========================================================================= with Ada.Text_IO, GNAT.Sockets; procedure Main is use GNAT.Sockets; Address : Sock_Addr_Type := (Family_Inet, Inet_Addr( "127.0.0.1" ), 5555); Socket : Socket_Type; Channel : Stream_Access; Data : String := "hello"; begin Initialize; Create_Socket( Socket ); Connect_Socket( Socket, Address ); Channel := Stream( Socket ); String'Write( Channel, Data ); String'Read( Channel, Data ); Ada.Text_IO.Put_Line( Data ); Close_Socket( Socket ); Finalize; end Main; ========================================================================= this is my Python server: ========================================================================= import socket def main(): server = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) server.bind( ('127.0.0.1', 5555) ) server.listen( 5 ) client, addr = server.accept() data = '' while len( data ) != 5: data += client.recv( 5 ) print data client.send( "world" ) server.close() if __name__ == '__main__': main() ========================================================================= they work together like a charm. ok, ok, ok, i admit it i cheated !! the ada client sends a 5 character long string and waits for a 5 character long string, but the server sends a 5 character long string... if the server sent "grabuuuu !", the client would only get "grabu". as i already pointed to you on fr.comp.lang.ada, what you get from a read is dependant on the PROTOCOL ! all the problem encountered when using streams with sockets are protocol problems: people sends some data on the socket and expect something else at the other end. in my example, i used a simple protocol: the client send 5 characters on the socket then the server sends back 5 other characters. the protocol is the same on both sides. when trying to sends strings over the network, you have to take into account that no 2 languages uses the same representation for strings: C strings are null-terminated, Ada strings are arrays of character with a lower and an upper bound, pascal strings are array of chars with only an upper bound... if you just send c strings and expect ada strings, you only get garbage ! this is the point of knowing ARM95 13.13.2: it allows you to know HOW data are pushed onto streams, thus allowing you to know how to read them back. eventually, you can write your own 'Read and 'Write procedures so that you are sure of what you have on the stream... ultimately, you can combine all the techniques to define powerful language-independant protocols ! -- rien