Package: GNAT.Sockets

Dependencies

with Ada.Streams;

Description

This package provides an interface to the sockets communication facility provided on many operating systems. Currently this is implemented on all GNAT ports except for VMS. Sockets are designed to provide a consistent communication facility between applications. This package provides an Ada-like interface similar to the one proposed as part of the BSD socket layer. This is a system independant thick binding. Here is a typical example of what you can do.

Header

package GNAT.Sockets is
 

Known child units

GNAT.Sockets.Constants(package)
GNAT.Sockets.Linker_Options(package)
GNAT.Sockets.Thin(package)

Exceptions

Host_Error
Exception raised by the two following procedures. Once raised, its message contains a string describing the error code. This exception is raised when an host entry can not be retrieved.
Socket_Error
There is only one exception in this package to deal with an error during a socket routine. Once raised, its message contains a string describing the error code.

Type Summary

Error_Type derived from Integer
Family_Type
Host_Entry_Type
Primitive Operations:  Addresses, Addresses_Length, Aliases, Aliases_Length, Get_Host_By_Address, Get_Host_By_Name, Official_Name
Inet_Addr_Type
Primitive Operations:  Addresses, Get_Host_By_Address, Image, Inet_Addr
Level_Type
Mode_Type
Option_Name
Option_Type
Primitive Operations:  Get_Socket_Option, Set_Socket_Option
Port_Type derived from Natural
Request_Name
Request_Type
Primitive Operations:  Control_Socket
Selector_Access
Selector_Status
Selector_Type (limited type)
Primitive Operations:  Abort_Selector, Check_Selector, Close_Selector, Create_Selector
Shutmode_Type
Sock_Addr_Type
Primitive Operations:  Accept_Socket, Bind_Socket, Connect_Socket, Get_Address, Get_Peer_Name, Get_Socket_Name, Image, Receive_Socket, Send_Socket, Stream
Socket_Set_Type
Primitive Operations:  Check_Selector, Clear, Empty, Is_Empty, Is_Set, Set
Socket_Type
Primitive Operations:  Accept_Socket, Bind_Socket, Clear, Close_Socket, Connect_Socket, Control_Socket, Create_Socket, Get_Peer_Name, Get_Socket_Name, Get_Socket_Option, Image, Is_Set, Listen_Socket, Receive_Socket, Receive_Socket, Send_Socket, Send_Socket, Set, Set_Socket_Option, Shutdown_Socket, Stream, Stream, To_C
Stream_Access

Constants and Named Numbers

Any_Inet_Addr : constant Inet_Addr_Type;
Any_Port : constant Port_Type;
Forever : constant Duration;
No_Inet_Addr : constant Inet_Addr_Type;
No_Port : constant Port_Type;
No_Sock_Addr : constant Sock_Addr_Type;
No_Socket : constant Socket_Type;

Other Items:

procedure Initialize (Process_Blocking_IO : Boolean := False);
Initialize must be called before using any socket routines. If the thread library provides process blocking IO - basically with FSU threads - GNAT.Sockets should be initialized with a value of True to simulate thread blocking IO. Further calls to Initialize will be ignored.

procedure Finalize;
After Finalize is called it is not possible to use any routines exported in by this package. This procedure is idempotent.

type Socket_Type is private;
Sockets are used to implement a reliable bi-directional point-to-point, stream-based connections between hosts. No_Socket provides a special value to denote uninitialized sockets.

function Image (Socket : Socket_Type) return String;
Return a printable string for Socket

function To_C (Socket : Socket_Type) return Integer;
Return a file descriptor to be used by external subprograms especially the C functions that are not yet interfaced in this package.

type Family_Type is (Family_Inet, Family_Inet6);
Address family (or protocol family) identifies the communication domain and groups protocols with similar address formats. IPv6 will soon be supported.

type Mode_Type is (Socket_Stream, Socket_Datagram);
Stream sockets provide connection-oriented byte streams. Datagram sockets support unreliable connectionless message based communication.

type Shutmode_Type is (Shut_Read, Shut_Write, Shut_Read_Write);
When a process closes a socket, the policy is to retain any data queued until either a delivery or a timeout expiration (in this case, the data are discarded). A finer control is available through shutdown. With Shut_Read, no more data can be received from the socket. With_Write, no more data can be transmitted. Neither transmission nor reception can be performed with Shut_Read_Write.

type Port_Type is new Natural;
Classical port definition. No_Port provides a special value to denote uninitialized port. Any_Port provides a special value enabling all ports.

type Inet_Addr_Type (Family : Family_Type := Family_Inet) is private;
An Internet address depends on an address family (IPv4 contains 4 octets and Ipv6 contains 16 octets). Any_Inet_Address is a special value treated like a wildcard enabling all addresses. No_Inet_Addr provides a special value to denote uninitialized inet addresses.

type Sock_Addr_Type (Family : Family_Type := Family_Inet) is record
   Addr : Inet_Addr_Type (Family);
   Port : Port_Type;
end record;
Socket addresses fully define a socket connection with a protocol family, an Internet address and a port. No_Sock_Addr provides a special value for uninitialized socket addresses.

function Image (Value : Inet_Addr_Type) return String;
Return an image of an Internet address. IPv4 notation consists in 4 octets in decimal format separated by dots. IPv6 notation consists in 16 octets in hexadecimal format separated by colons (and possibly dots).

function Image (Value : Sock_Addr_Type) return String;
Return inet address image and port image separated by a colon.

function Inet_Addr (Image : String) return Inet_Addr_Type;
Convert address image from numbers-and-dots notation into an inet address.

type Host_Entry_Type
  (Aliases_Length, Addresses_Length : Natural) is private;
Host entries provide a complete information on a given host: the official name, an array of alternative names or aliases and array of network addresses.

function Official_Name (E : Host_Entry_Type) return String;
Return official name in host entry

function Aliases_Length (E : Host_Entry_Type) return Natural;
Return number of aliases in host entry

function Addresses_Length (E : Host_Entry_Type) return Natural;
Return number of addresses in host entry

function Aliases
  (E    : Host_Entry_Type;
   N    : Natural := 1)
   return String;
Return N'th aliases in host entry. The first index is 1.

function Addresses
  (E    : Host_Entry_Type;
   N    : Natural := 1)
   return Inet_Addr_Type;
Return N'th addresses in host entry. The first index is 1.

function Get_Host_By_Address
  (Address : Inet_Addr_Type;
   Family  : Family_Type := Family_Inet)
   return    Host_Entry_Type;
Return host entry structure for the given inet address

function Get_Host_By_Name
  (Name : String)
   return Host_Entry_Type;
Return host entry structure for the given host name

function Host_Name return String;
Return the name of the current host

type Error_Type is new Integer;
Errors are described by an enumeration type. There is only one exception Socket_Error in this package to deal with an error during a socket routine. Once raised, its message contains a string describing the error code.

type Level_Type is (
  Socket_Level,
  IP_Protocol_For_IP_Level,
  IP_Protocol_For_UDP_Level,
  IP_Protocol_For_TCP_Level);
Get_Socket_Options and Set_Socket_Options manipulate options associated with a socket. Options may exist at multiple protocol levels in the communication stack. Socket_Level is the uppermost socket level. There are several options available to manipulate sockets. Each option has a name and several values available. Most of the time, the value is a boolean to enable or disable this option.

type Option_Name is (
  Keep_Alive,      -- Enable sending of keep-alive messages
  Reuse_Address,   -- Allow bind to reuse local address
  Broadcast,       -- Enable datagram sockets to recv/send broadcast packets
  Send_Buffer,     -- Set/get the maximum socket send buffer in bytes
  Receive_Buffer,  -- Set/get the maximum socket recv buffer in bytes
  Linger,          -- Shutdown wait for msg to be sent or timeout occur
  Error,           -- Get and clear the pending socket error
  No_Delay,        -- Do not delay send to coalesce packets (TCP_NODELAY)
  Add_Membership,  -- Join a multicast group
  Drop_Membership, -- Leave a multicast group
  Multicast_TTL,   -- Indicates the time-to-live of sent multicast packets
  Multicast_Loop);
Sent multicast packets are looped to the local socket

type Option_Type (Name : Option_Name := Keep_Alive) is record
   case Name is
      when Keep_Alive      |
           Reuse_Address   |
           Broadcast       |
           Linger          |
           No_Delay        |
           Multicast_Loop  =>
         Enabled : Boolean;

         case Name is
            when Linger    =>
               Seconds : Natural;
            when others    =>
               null;
         end case;

      when Send_Buffer     |
           Receive_Buffer  =>
         Size : Natural;

      when Error           =>
         Error : Error_Type;

      when Add_Membership  |
           Drop_Membership =>
         Multiaddr : Inet_Addr_Type;
         Interface : Inet_Addr_Type;

      when Multicast_TTL   =>
         Time_To_Live : Natural;

   end case;
end record;
There are several controls available to manipulate sockets. Each option has a name and several values available. These controls differ from the socket options in that they are not specific to sockets but are available for any device.

type Request_Name is (
   Non_Blocking_IO,  --  Cause a caller not to wait on blocking operations.
   N_Bytes_To_Read);
Return the number of bytes available to read

type Request_Type (Name : Request_Name := Non_Blocking_IO) is record
   case Name is
      when Non_Blocking_IO =>
         Enabled : Boolean;

      when N_Bytes_To_Read =>
         Size : Natural;

   end case;
end record;

procedure Create_Socket
  (Socket : out Socket_Type;
   Family : Family_Type := Family_Inet;
   Mode   : Mode_Type   := Socket_Stream);
Create an endpoint for communication. Raise Socket_Error on error.

procedure Accept_Socket
  (Server  : Socket_Type;
   Socket  : out Socket_Type;
   Address : out Sock_Addr_Type);
Extract the first connection request on the queue of pending connections, creates a new connected socket with mostly the same properties as Server, and allocates a new socket. The returned Address is filled in with the address of the connection. Raise Socket_Error on error.

procedure Bind_Socket
  (Socket  : Socket_Type;
   Address : Sock_Addr_Type);
Once a socket is created, assign a local address to it. Raise Socket_Error on error.

procedure Close_Socket (Socket : Socket_Type);
Close a socket and more specifically a non-connected socket. Fail silently.

procedure Connect_Socket
  (Socket : Socket_Type;
   Server : in out Sock_Addr_Type);
Make a connection to another socket which has the address of Server. Raise Socket_Error on error.

procedure Control_Socket
  (Socket  : Socket_Type;
   Request : in out Request_Type);
Obtain or set parameter values that control the socket. This control differs from the socket options in that they are not specific to sockets but are avaiable for any device.

function Get_Peer_Name (Socket : Socket_Type) return Sock_Addr_Type;
Return the peer or remote socket address of a socket. Raise Socket_Error on error.

function Get_Socket_Name (Socket : Socket_Type) return Sock_Addr_Type;
Return the local or current socket address of a socket. Raise Socket_Error on error.

function Get_Socket_Option
  (Socket : Socket_Type;
   Level  : Level_Type := Socket_Level;
   Name   : Option_Name)
   return   Option_Type;
Get the options associated with a socket. Raise Socket_Error on error.

procedure Listen_Socket
  (Socket : Socket_Type;
   Length : Positive := 15);
To accept connections, a socket is first created with Create_Socket, a willingness to accept incoming connections and a queue Length for incoming connections are specified. Raise Socket_Error on error.

procedure Raise_Socket_Error (Error : Error_Type);
Raise Socket_Error with an exception message describing the error code.

procedure Receive_Socket
  (Socket : Socket_Type;
   Item   : out Ada.Streams.Stream_Element_Array;
   Last   : out Ada.Streams.Stream_Element_Offset);
Receive message from Socket. Last is the index value such that Item (Last) is the last character assigned. Note that Last is set to Item'First - 1 when the socket has been closed by peer. This is not an error and no exception is raised. Raise Socket_Error on error.

procedure Receive_Socket
  (Socket : Socket_Type;
   Item   : out Ada.Streams.Stream_Element_Array;
   Last   : out Ada.Streams.Stream_Element_Offset;
   From   : out Sock_Addr_Type);
Receive message from Socket. If Socket is not connection-oriented, the source address From of the message is filled in. Last is the index value such that Item (Last) is the last character assigned. Raise Socket_Error on error.

procedure Send_Socket
  (Socket : Socket_Type;
   Item   : Ada.Streams.Stream_Element_Array;
   Last   : out Ada.Streams.Stream_Element_Offset);
Transmit a message to another socket. Note that Last is set to Item'First when socket has been closed by peer. This is not an error and no exception is raised. Raise Socket_Error on error;

procedure Send_Socket
  (Socket : Socket_Type;
   Item   : Ada.Streams.Stream_Element_Array;
   Last   : out Ada.Streams.Stream_Element_Offset;
   To     : Sock_Addr_Type);
Transmit a message to another socket. The address is given by To. Raise Socket_Error on error;

procedure Set_Socket_Option
  (Socket : Socket_Type;
   Level  : Level_Type := Socket_Level;
   Option : Option_Type);
Manipulate socket options. Raise Socket_Error on error.

procedure Shutdown_Socket
  (Socket : Socket_Type;
   How    : Shutmode_Type := Shut_Read_Write);
Shutdown a connected socket. If How is Shut_Read, further receives will be disallowed. If How is Shut_Write, further sends will be disallowed. If how is Shut_Read_Write, further sends and receives will be disallowed. Fail silently.

type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
Same interface as Ada.Streams.Stream_IO

function Stream
  (Socket : Socket_Type)
   return   Stream_Access;
Associate a stream with a stream-based socket that is already connected.

function Stream
  (Socket  : Socket_Type;
   Send_To : Sock_Addr_Type)
   return    Stream_Access;
Associate a stream with a datagram-based socket that is already bound. Send_To is the socket address to which messages are being sent.

function Get_Address
  (Stream : Stream_Access)
  return Sock_Addr_Type;
Return the socket address from which the last message was received.

type Socket_Set_Type is private;
This type allows to manipulate sets of sockets. It allows to wait for events on multiple endpoints at one time. This is an access type on a system dependent structure. To avoid memory leaks it is highly recommended to clean the access value with procedure Empty.

procedure Clear (Item : in out Socket_Set_Type; Socket : Socket_Type);
Remove Socket from Item

procedure Set   (Item : in out Socket_Set_Type; Socket : Socket_Type);
Insert Socket into Item

procedure Empty (Item : in out Socket_Set_Type);
Remove all Sockets from Item and deallocate internal data

function Is_Empty
  (Item : Socket_Set_Type)
   return  Boolean;
Return True if Item is empty

function Is_Set
  (Item   : Socket_Set_Type;
   Socket : Socket_Type)
   return   Boolean;
Return True if Socket is present in Item

type Selector_Type is limited private;

type Selector_Access is access all Selector_Type;

procedure Create_Selector (Selector : out Selector_Type);
Create a new selector

procedure Close_Selector (Selector : in out Selector_Type);
Close Selector and all internal descriptors associated

type Selector_Status is (Completed, Expired, Aborted);

procedure Check_Selector
  (Selector     : in out Selector_Type;
   R_Socket_Set : in out Socket_Set_Type;
   W_Socket_Set : in out Socket_Set_Type;
   Status       : out Selector_Status;
   Timeout      : Duration := Forever);
Return when one Socket in R_Socket_Set has some data to be read or if one Socket in W_Socket_Set is ready to receive some data. In these cases Status is set to Completed and sockets that are ready are set in R_Socket_Set or W_Socket_Set. Status is set to Expired if no socket was ready after a Timeout expiration. Status is set to Aborted if an abort signal as been received while checking socket status. As this procedure returns when Timeout occurs, it is a design choice to keep this procedure process blocking. Note that a Timeout of 0.0 returns immediatly.

procedure Abort_Selector (Selector : Selector_Type);
Send an abort signal to the selector.

private

   --  Implementation-defined ...
end GNAT.Sockets;