comp.lang.ada
 help / color / mirror / Atom feed
From: Simon Wright <simon@pushface.org>
Subject: Re: "broken pipe" while reading/writing stream-based sockets
Date: Fri, 20 May 2005 21:02:49 +0100
Date: 2005-05-20T21:02:49+01:00	[thread overview]
Message-ID: <m264xdvf6e.fsf@grendel.local> (raw)
In-Reply-To: 1116601288.424625.176760@g14g2000cwa.googlegroups.com

"fabio de francesco" <fmdf@tiscali.it> writes:

> Florian Weimer wrote:
>> * fabio de francesco:
>>
>> > 1) Why does this server sometimes crash with "Broken Pipe"?
>>
>> This usually indicates that the client closed its end of the
>> connection while the server was still sending data.  Maybe this
>> happens because your code does not deal with partial reads/writes.
>>
>> > 2) It seems that using Input/Output instead of Read/Write never
> causes
>> > "Broken Pipe". Why?
>>
>> The stream implementation provided by GNAT.Sockets deals with partial
>> reads and writes.
>
> In C I know how to read() in a loop and increment a pointer to a buffer
> (a C string) while receiving characters until there are no more of
> them. It is sufficient that read() returns how many characters has
> already read and some little math involving buffer size.
>
> In Ada I don't know how to do it... Can you please give me any
> suggestions?

I'm sure there's a better way .. but this is what I did

   function Read_Request (From : Socket_Type) return String is
      Tmp : Stream_Element_Array (1 .. 2048);
      Last : Stream_Element_Offset := Tmp'First - 1;
      Next : Stream_Element_Offset;
      Termination : constant Stream_Element_Array :=
        (Character'Pos (CR),
         Character'Pos (LF),
         Character'Pos (CR),
         Character'Pos (LF));
      S : Stream_Access := Stream (From);
   begin

      --  We need to read the whole request from the client. Of course
      --  we don't know how long it is. We can't just issue an
      --  Ada.Streams.Read for a large buffer, because the client may
      --  not have sent that much and if she hasn't we'll block until
      --  she gives up and closes the socket. So we read a character
      --  at a time until we've got the CR/LF/CR/LF which terminates
      --  the line.
      loop
         Ada.Streams.Read (Stream => S.all,
                           Item => Tmp (Last + 1 .. Last + 1),
                           Last => Next);
         exit when Next = Last;
         Last := Last + 1;
         exit when Last >= Termination'Length
           and then Tmp (Last - 3 .. Last) = Termination;
         exit when Last = Tmp'Last;
      end loop;

      Free_Stream (S);

      declare
         Result : String (1 .. Natural (Last));
         pragma Import (Ada, Result);
         for Result'Address use Tmp'Address;
      begin
         return Result;
      end;

   end Read_Request;



      parent reply	other threads:[~2005-05-20 20:02 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-05-10 23:02 "broken pipe" while reading/writing stream-based sockets fabio de francesco
2005-05-11 10:46 ` Adrien Plisson
2005-05-11 15:01   ` fabio de francesco
2005-05-11 21:18 ` Simon Wright
2005-05-11 23:30   ` fabio de francesco
2005-05-13 20:18   ` fabio de francesco
2005-05-13 20:25     ` fabio de francesco
2005-05-14 20:39     ` Jeffrey Carter
2005-05-14 21:27 ` Florian Weimer
2005-05-20 15:01   ` fabio de francesco
2005-05-20 17:52     ` tmoran
2005-05-20 20:02     ` Simon Wright [this message]
replies disabled

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