UDP.
This is a simple library for Ada, to replace the asinine GNATSockets item.
Supported:
- Unixlike OS back-end.
- Open/close datagram socket on given local IP and port.
- Transmit datagrams of fixed length.
- Receive (blocking) datagrams of fixed length, rejecting shorts, saving the originator's IP/port.
- Handle all possible OS error conditions.
Permanently unsupported:
You will need:
- GNAT.
- udp_genesis.vpatch
- udp_genesis.vpatch.asciilifeform.sig
- udp_errata.asciilifeform.vpatch
- udp_errata.asciilifeform.vpatch.asciilifeform.sig
Edit (9/27) : diana_coman graciously baked a Keccak-V regrind of this item. I will mirror it here, along with her seals and mine. (I have taken the liberty of reformatting the file names to follow my sorting convention, this does not affect GPG signatures, and will not AFAIK confuse any existing Vtron.)
- udp_errata.asciilifeform.kv.vpatch
- udp_errata.asciilifeform.kv.vpatch.asciilifeform.sig
- udp_errata.asciilifeform.kv.vpatch.diana_coman.sig
Add the above vpatch and seal to your V-set, and press to udp_errata.asciilifeform.vpatch.
The lib itself is 583 589 LOC, including commentary and C glue.
The demo set is reproduced below:
udp_echo_demo.adb:
with Ada.Text_IO; use Ada.Text_IO; with UDP; procedure UDP_Echo_Demo is Socket : UDP.Socket; Local_Endpoint : UDP.Endpoint := (Address => UDP.INADDR_ANY, Port => 7000); Received_Payload : UDP.Payload; Received_Origin : UDP.Endpoint; Received_Valid : Boolean; begin Put_Line("Opening socket on local endpoint " & UDP.IP_To_String(Local_Endpoint.Address) & " :" & UDP.IP_Port'Image(Local_Endpoint.Port) & "..."); UDP.Open_Socket(Socket, Local_Endpoint); Put_Line("Waiting for payload..."); UDP.Receive(Socket, Received_Origin, Received_Payload, Received_Valid); Put_Line("Received payload from " & UDP.IP_To_String(Received_Origin.Address) & " :" & UDP.IP_Port'Image(Received_Origin.Port) & "..."); if Received_Valid then Put_Line("Sending received payload back to originator..."); UDP.Transmit(Socket, Received_Origin, Received_Payload); else Put_Line("Received short payload, ignored."); end if; UDP.Close_Socket(Socket); Put_Line("Done."); end UDP_Echo_Demo;
udp_tx_demo.adb:
with Ada.Text_IO; use Ada.Text_IO; with Interfaces; use Interfaces; with UDP; use UDP; procedure UDP_Tx_Demo is Socket : UDP.Socket; Local_Endpoint : UDP.Endpoint := (Address => UDP.INADDR_ANY, Port => 5000); Remote_Endpoint : UDP.Endpoint := (Address => UDP.IP_From_String("0.0.0.0"), Port => 7000); ----- Dulap test, replace with your own ----- -- Remote_Endpoint : UDP.Endpoint -- := (Address => UDP.IP_From_String("161.0.121.200"), -- Port => 7000); ---------------------------------------------- Sent_Payload : UDP.Payload; Received_Payload : UDP.Payload; Received_Origin : UDP.Endpoint; Received_Valid : Boolean; begin Put_Line("Generating " & UDP.Payload_Size'Image(Sent_Payload'Length) & "-byte turd..."); for I in Sent_Payload'Range loop Sent_Payload(I) := Unsigned_8(I mod 256); end loop; Put_Line("Opening socket on local endpoint " & UDP.IP_To_String(Local_Endpoint.Address) & " :" & UDP.IP_Port'Image(Local_Endpoint.Port) & "..."); UDP.Open_Socket(Socket, Local_Endpoint); Put_Line("Sending turd to " & UDP.IP_To_String(Remote_Endpoint.Address) & " :" & UDP.IP_Port'Image(Remote_Endpoint.Port) & "..."); UDP.Transmit(Socket, Remote_Endpoint, Sent_Payload); Put_Line("Waiting for echo..."); UDP.Receive(Socket, Received_Origin, Received_Payload, Received_Valid); Put_Line("Received payload from " & UDP.IP_To_String(Received_Origin.Address) & " :" & UDP.IP_Port'Image(Received_Origin.Port) & "..."); if Received_Valid then if Received_Payload = Sent_Payload then Put_Line("Echo came back equal to the send turd!"); else Put_Line("Echo came back mutilated!"); end if; else Put_Line("Received short payload, ignored."); end if; UDP.Close_Socket(Socket); Put_Line("Done."); end UDP_Tx_Demo;
Now compile the echodemo and txdemo:
cd echodemo gprbuild cd ../txdemo gprbuild
Run these as-is, or try the variant where the two are actually on physically-separated machines.