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,8f6dc5bfebaf357f X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news1.google.com!news2.google.com!proxad.net!newsfeed.stueberl.de!newsfeed.vmunix.org!peer-uk.news.demon.net!kibo.news.demon.net!news.demon.co.uk!demon!not-for-mail From: Simon Wright Newsgroups: comp.lang.ada Subject: Re: "broken pipe" while reading/writing stream-based sockets Date: Fri, 20 May 2005 21:02:49 +0100 Organization: Pushface Message-ID: References: <1115766179.505983.40960@f14g2000cwb.googlegroups.com> <87zmuxqz0r.fsf@deneb.enyo.de> <1116601288.424625.176760@g14g2000cwa.googlegroups.com> NNTP-Posting-Host: pogner.demon.co.uk Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: news.demon.co.uk 1116619369 5790 62.49.19.209 (20 May 2005 20:02:49 GMT) X-Complaints-To: abuse@demon.net NNTP-Posting-Date: Fri, 20 May 2005 20:02:49 +0000 (UTC) Cancel-Lock: sha1:+pvlX3uJVw1NIWkSzJo5H5P10uQ= User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (darwin) Xref: g2news1.google.com comp.lang.ada:11107 Date: 2005-05-20T21:02:49+01:00 List-Id: "fabio de francesco" 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;