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=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,c58b7bd180ea81b2 X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!postnews.google.com!i24g2000prf.googlegroups.com!not-for-mail From: Adam Beneschan Newsgroups: comp.lang.ada Subject: Re: Problems with Ada.Streams.Read (blocking) Date: Fri, 8 Aug 2008 07:48:42 -0700 (PDT) Organization: http://groups.google.com Message-ID: <103f4912-d96b-4c11-b9b2-d7a6d6ffcff3@i24g2000prf.googlegroups.com> References: NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: posting.google.com 1218206922 15992 127.0.0.1 (8 Aug 2008 14:48:42 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Fri, 8 Aug 2008 14:48:42 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: i24g2000prf.googlegroups.com; posting-host=66.126.103.122; posting-account=duW0ogkAAABjRdnxgLGXDfna0Gc6XqmQ User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.12) Gecko/20050922 Fedora/1.7.12-1.3.1,gzip(gfe),gzip(gfe) Xref: g2news1.google.com comp.lang.ada:1552 Date: 2008-08-08T07:48:42-07:00 List-Id: On Aug 8, 6:24 am, Dennis Hoppe wrote: > Hi, > > I've written a minimal example to access an ftp server (like FileZilla). > First, let's have a look at the code snippet: > > -- START > with Ada.Text_IO; > with Ada.Streams; > with GNAT.Sockets; use GNAT.Sockets; > use type Ada.Streams.Stream_Element_Count; > > procedure Test is > Client: Socket_Type; > Address: Sock_Addr_Type; > Channel: Stream_Access; > Data : Ada.Streams.Stream_Element_Array (1 .. 1); > Offset : Ada.Streams.Stream_Element_Count; > > begin > Initialize; > Create_Socket(Client); > Address.Addr := Inet_Addr("127.0.0.1"); > Address.Port := 21; > Connect_Socket (Client,Address); > Channel := Stream(Client); > > loop -- reads in the welcome message > Ada.Streams.Read (Channel.all, Data(1..1), Offset); > exit when Offset = 0; > -- alternative: exit when Offset /= Data'Last > for I in 1 .. Offset loop > Ada.Text_IO.Put (Character'Val (Data (I))); > end loop; > end loop; > end Test; > -- END > > The problem is, that Ada.Streams.Read is blocking, if the end of the > stream is reached. I found many examples, that outline, that the > variable Offset will be 0, if no further elements are on the stream. > But this seems not to be the case, unfortunately. > > For a ftp server/client situation, each command is terminate by , > so I enhanced the exit condition to: > > loop > Ada.Streams.Read (Channel.all, Data(1..2), Offset); > exit when (Character'Val (Data(1)) = ASCII.CR and Character'Val > (Data(2)) = ASCII.LF); > -- code omitted > end loop; > > Of course, the Stream_Element_Array is enhanced to (1..2). > > This approach works very well, but some ftp commands send a messages > over several lines. I do not know in advance, how many lines I should > read in. Subsequently, Ada.Streams.Read has to be called in a loop, > which will eventually block, again. > > How can I query the stream, if new elements are ready to read? I'm not familiar with GNAT.Sockets, but looking at the spec it appears that there are a couple routines that might help: Control_Socket which lets you specify non-blocking I/O, and Check_Selector which I think can be used to query whether data is available, if you give it a Timeout of zero. Anyway, I haven't tried anything and I have no idea whether it's appropriate for your problem, but it seems like it might help. If not, my apologies. -- Adam