From: anon@att.net
Subject: Re: Help writing first daemon Heres a Server
Date: Sun, 9 Sep 2012 07:26:49 +0000 (UTC)
Date: 2012-09-09T07:26:49+00:00 [thread overview]
Message-ID: <k2hgbn$5d3$1@speranza.aioe.org> (raw)
In-Reply-To: 3b3a796d-50e0-4304-9f8d-295fb2ed0e82@googlegroups.com
--
-- TCP/IP Echo Service Daemon, based on RFC 342 and RFC 862
-- Normally, a Sender program that accepts a word or quoted
-- sentence from command line is transmitted to the server and
-- the return message is displayed.
--
-- This Daemon was tested using "Ada Dual TCP/IP Stacks" using
-- IPv6 and Linux IPv4,
--
--
-- Protocol: TCP
-- Protocol: UDP not setup at this time.
--
-- Usage: Listener
--
-- Tester: Telnet <hostname> -port 7
-- Example: Telnet 127.0.0.1 7
--
-- While telnet operational every character including control
-- characters will be echoed
--
with Ada.Characters.Latin_9 ;
with Ada.Exceptions ;
with Ada.Text_IO ;
with GNAT.Sockets ; -- GNAT to reg OS
-- with Sockets ; -- Ada TCP/IP Stacks
use Ada.Characters.Latin_9 ;
use Ada.Exceptions ;
use Ada.Text_IO ;
use GNAT.Sockets ;
-- use Sockets ; -- Ada TCP/IP Stacks
procedure Listener is
--
-- Operational options
--
-- Set to True to use IPv6, But some GNAT.Socket packages, are
-- not setup to handle IPv6 yet. One way to check is to look at
-- the body for the "Bind" function. Because the "Bind" function
-- raises a exception, if IPv6 is use, for those packages that
-- are IPv4 only.
--
IP_V6 : constant Boolean := False ;
--
-- Displays a logging message if True
--
LOGGING : constant Boolean := False ;
task type Echo is
entry Start ( Incoming : Socket_Type ) ;
end Echo ;
type Echo_Access is access Echo ;
type Sock_Addr_Access is access all Sock_Addr_Type ;
--
-- Echo -- the main processthat preforms the echo operation
-- -- one problem is there is no recovery of memory use
-- by this task once the task ends.
--
task body Echo is
Data : Character ;
Channel : Stream_Access ;
Socket : Socket_Type ;
begin
accept Start ( Incoming : Socket_Type ) do
Socket := Incoming ;
end Start ;
Channel := Stream ( Socket ) ;
loop
Data := Character ' Input ( Channel ) ;
exit when Data = ASCII.Nul ;
Character ' Output ( Channel, Data ) ;
end loop ;
Close_Socket ( Socket ) ;
exception
when Socket_Error =>
Put_Line ( "Connection closed" ) ;
Close_Socket ( Socket ) ;
end Echo ;
--
Accepting_Socket : Socket_Type ;
Incoming_Socket : Socket_Type ;
Address : Sock_Addr_Access ;
Dummy : Echo_Access ;
TCP_Error : exception ;
begin
--
-- Create Socket and sets stacks. With error checking to insure
-- stacks is valid because some system only have IPv4 and other
-- have remove IPv4. If both stacks are installed and GNAT
-- allows both, then use IPv6.
--
if IP_V6 then
begin
--
-- set IPv6
--
Create_Socket ( Accepting_Socket, Family_Inet6, Socket_Stream ) ;
Address := new Sock_Addr_Type ( Family_Inet6 );
exception
when Socket_Error =>
Put_Line ( "Error: IP version 6 is not supported" ) ;
raise TCP_Error ;
end ;
else
begin
--
-- set Default IPv4
--
Create_Socket ( Accepting_Socket ) ;
Address := new Sock_Addr_Type ;
exception
when Socket_Error =>
Put_Line ( "Error: IP version 4 is not supported" ) ;
raise TCP_Error ;
end ;
end if ;
--
-- Address.Addr is current host can be localhost
-- Address.Port is 7 based on RFC 342 update RFC 862
--
Address.all.Addr := Addresses ( Get_Host_By_Name ( Host_Name ), 1 ) ;
Address.all.Port := 7 ;
--
-- Bind Address to socket
--
Bind_Socket ( Accepting_Socket, Address.all ) ;
--
-- Set stacks to receive connect events
--
Listen_Socket ( Accepting_Socket ) ;
--
-- Handle connections
--
loop
--
-- Wait until client request connect then accept connection
--
Accept_Socket ( Accepting_Socket,
Incoming_Socket, Address.all ) ;
--
-- Log message, if required
--
if LOGGING then
Put ( "Received From: " ) ;
Put ( Image ( Address.all ) ) ;
end if ;
--
-- Create a single usage task to handle daemon process
-- task will die once connection is ended. In this design
-- there is a possible memory leak because once the task
-- dies there is no memory recover of the dead task.
--
Dummy := new Echo ;
Dummy.Start ( Incoming_Socket ) ;
end loop ;
exception
when TCP_Error =>
Put_Line ( "Error: Server was not initialized" ) ;
when others =>
Put_Line ( "Error: Server is beening shutdown" ) ;
Shutdown_Socket ( Accepting_Socket, Shut_Read_Write ) ;
end Listener ;
In <3b3a796d-50e0-4304-9f8d-295fb2ed0e82@googlegroups.com>, Patrick <patrick@spellingbeewinnars.org> writes:
>
>Hi Everyone
>
>I am setting out to write my first daemon. There seems to be a lot of optio=
>ns for inter-process communication on posix systems. I am planning on desig=
>ning a scientific instrument control server that will control ports, like t=
>he serial port, based on signals it is sent. It will also collect data from=
> instruments and store the data(I was thinking in a postgresql database).
>
>I just need signals passed on one machine so yaml4 seems like overkill. I w=
>as thinking that I could write many little commands, with each command spec=
>ific to an instrument it is designed to control and the daemon as more gene=
>ral infrastructure(basically middleware), so it wouldn't really be a parent=
>/child relationship. I'm guessing plain old pipes are out.
>
>Does FIFO/names pipes sound reasonable for this sort of thing? I am concern=
>ed that with many commands acting on the daemon there will be too much over=
>head with these commands creating file handlers.
>
>I am also going to control instruments over Ethernet anyways so would inves=
>ting time in socket programming solve two problems by making it a socket ba=
>sed server? Once the socket is set up by the daemon, the smaller "satellite=
>" commands would not need as much overhead to connect to a port as they wou=
>ld to create a file handler, would they?
>
>Lastly, this will be done in Ada where ever possible, is there an Ada orien=
>ted way to do this sort of thing?
>
>Thanks for reading-Patrick
next prev parent reply other threads:[~2012-09-14 17:42 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-07 22:05 Help writing first daemon Patrick
2012-09-08 8:06 ` Dmitry A. Kazakov
2012-09-11 14:38 ` Maciej Sobczak
2012-09-11 15:13 ` Dmitry A. Kazakov
2012-09-11 20:50 ` Maciej Sobczak
2012-09-12 7:16 ` Dmitry A. Kazakov
2012-09-08 8:08 ` björn lundin
2012-09-08 11:22 ` Patrick
2012-09-09 7:26 ` anon [this message]
2012-09-09 12:26 ` Patrick
2012-09-11 14:18 ` Julian Leyh
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox