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: a07f3367d7,e8c6974546bc3f7f X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Received: by 10.66.80.8 with SMTP id n8mr4296996pax.17.1354084461666; Tue, 27 Nov 2012 22:34:21 -0800 (PST) Path: s9ni15761pbb.0!nntp.google.com!border1.nntp.dca.giganews.com!border4.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!novia!news-hub.siol.net!news.mi.ras.ru!aspen.stu.neva.ru!goblin-spool!goblin1!goblin.stu.neva.ru!eternal-september.org!feeder.eternal-september.org!mx04.eternal-september.org!.POSTED!not-for-mail From: Simon Wright Newsgroups: comp.lang.ada Subject: Re: Sockets Example Sought Date: Fri, 23 Nov 2012 23:08:01 +0000 Organization: A noiseless patient Spider Message-ID: References: <2012112311175432190-rblove@airmailnet> <2012112315585358568-rblove@airmailnet> Mime-Version: 1.0 Injection-Info: mx04.eternal-september.org; posting-host="f38d6453efa614aca652dfde0a80d954"; logging-data="2324"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19WHGLXBtzmXPv6WkVyLsI09IGOy/y7Sno=" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (darwin) Cancel-Lock: sha1:rC1VkakpSMoLFdSp2tjEj1HHfBc= sha1:2oznoau36azE6wRPV+nesxS91HM= Content-Type: text/plain Date: 2012-11-23T23:08:01+00:00 List-Id: Robert Love writes: > On 2012-11-23 18:32:52 +0000, Simon Wright said: > >> Robert Love writes: >> >>> Does anyone have an example of a multi-client server in Ada they >>> care to share? It should use the Gnat.Sockets package. I've seen >>> samples but they don't seem complete, or at least my understanding >>> isn't complete. >>> >>> Thanks in advance. >> >> task body Server in http://goo.gl/bXVw7 ? (lines 59 .. 143) > > What happens at line 120, the else clause on if Server = > Socket_Server? Is that where data is read in on the socket? > > I assume the client opens the socket and the server detects it, then > at various times the client makes data requests by sending string > data. Yes, pretty much. I've added some comments, see the end (these won't show up via the URL I gave, which is to a specific revision; ). > The Respond function called just seems to call HTTP.Respond, which is > not in this file. Yes. It's in ews-http.ad[sb]; HTTP.Initialize reads the HTTP request, HTTP.Find works out what sort of response is required, and HTTP.Respond generates it. -snippet- loop declare Read_Sockets : GNAT.Sockets.Socket_Set_Type; Status : GNAT.Sockets.Selector_Status; use type GNAT.Sockets.Selector_Status; begin -- Initialize Read_Sockets with the sockets in use -- (Write_Sockets remains empty, we don't care if a -- socket becomes writable; we'll just block in that -- case). GNAT.Sockets.Copy (Sockets, Read_Sockets); -- Wait until something happens on one of the sockets. GNAT.Sockets.Check_Selector (Selector, Read_Sockets, Write_Sockets, Status); if Status = GNAT.Sockets.Completed then -- This was a successful completion. Find out which -- socket woke us up and deal with it. If there was -- more than one, we'll find out next time round the -- loop. declare Socket : GNAT.Sockets.Socket_Type; use type GNAT.Sockets.Socket_Type; begin -- Which socket? GNAT.Sockets.Get (Read_Sockets, Socket); if Socket = Server_Socket then -- It was the server; a new client has called -- connect(). Accept the connection ... GNAT.Sockets.Accept_Socket (Server_Socket, Socket, Address); Trace (Logging_Via, "connection", Socket, Tracing); -- ... and add the new connected socket to the -- set of sockets in use. GNAT.Sockets.Set (Sockets, Socket); elsif Socket = GNAT.Sockets.No_Socket then -- None of our sockets has data/connection -- available; don't care why. Logging_Via ("server got No_Socket", Error); else -- There's an HTTP request to be read on one of -- our connected clients' sockets; deal with it. Trace (Logging_Via, "request", Socket, Tracing); Respond (Socket, Sockets, Logging_Via, Tracing); end if; end; else -- Unexpected, non-fatal error. Logging_Via ("server: Check_Selector returned " & Status'Img, Error); end if; -- Clean up. GNAT.Sockets.Empty (Read_Sockets); exception when E : others => Log (Logging_Via, "server failed in inner loop", With_Exception => E); end; end loop;