From: snoopysalive on
Come on guys, stop arguing. In the end, I've found a solution:

-----------------------------------------------------------------------
with Ada.Text_IO,
Ada.Exceptions,
Ada.Streams,
Ada.Unchecked_Deallocation,
GNAT.Sockets;
use Ada.Text_IO,
Ada.Exceptions,
Ada.Streams,
GNAT.Sockets;

procedure IP_Server is

BUFFER_SIZE : constant Positive := 1024;

type String_Access is access all String;

procedure Free is new Ada.Unchecked_Deallocation
(String, String_Access);

CRLF : constant String := ASCII.CR & ASCII.LF;
Host : constant String := "localhost";
Port : Port_Type := 7777;

Address : Sock_Addr_Type;
Server : Socket_Type;
Client : Socket_Type;
Channel : Stream_Access;

Data : Stream_Element_Array (1..1);
Offset : Stream_Element_Count;

Buffer : String_Access := new String (1..BUFFER_SIZE);
Cnt : Natural := 0;

Test : Float := 0.0;

begin -- IP_Server
Initialize;

Address.Addr := Addresses (Get_Host_By_Name (Host), 1);
Address.Port := Port;

Create_Socket (Server);
Set_Socket_Option (Server, Socket_Level, (Reuse_Address, True));
Bind_Socket (Server, Address);
Listen_Socket (Server);
Accept_Socket (Server, Client, Address);
Channel := Stream (Client);

Cnt := 0;
loop
Read (Channel.all, Data (1..1), Offset);
if Character'Val (Data (1)) = ASCII.CR or
Character'Val (Data (1)) = ASCII.LF or
Character'Val (Data (1)) = ASCII.NUL or
Offset = 0 then
exit;
else
Cnt := Cnt + 1;
Buffer.all (Cnt) := Character'Val (Data (1));
end if;
end loop;
-- Read values from client-stream character by character.
-- Reading should be stopped when Windows-linefeed or
-- NULL was found, because telnet seams to be sending
-- strings in a Windows-like format including the
-- terminating \0-character known from C-strings.

declare
Old : String_Access := Buffer;
begin
Buffer := new String'(Buffer (1..Cnt));
Free (Old);
end;
-- The buffer-size of Str is 1024 elements. It's necessary
-- to create a new String containing only relevant characters
-- for being able to process the message further.

declare
Pong : String := "pong" & CRLF;
O : Stream_Element_Array (1..Pong'length);
begin
if Buffer.all = "ping" then
for I in Pong'range loop
O (Stream_Element_Offset (I)) := Character'Pos (Pong (I));
end loop;
Write (Channel.all, O);
end if;
end;
-- If Buffer's message equals "ping" the server will
-- send "pong" to the client. "pong" must be casted
-- from String to Stream_Element_Array first.

Close_Socket (Client);
Close_Socket (Server);

Finalize;

exception when E : Socket_Error =>
Put_Line (Standard_Error, "Socket_Error => " & Exception_Message
(E));

end IP_Server;
-----------------------------------------------------------------------------------

Thanks to the thread under http://groups.google.com/group/comp.lang.ada/browse_thread/thread/c58b7bd180ea81b2
I found out how to read character by character from the client.
However, it's not very comfortable to cast the echo-string manually
but it's better than not being able to communicate with telnet or
other C-based clients.

Bye,
Matthias
From: anon on
But he wants to deal with Telnet. It states that in the title.

And actually, a complete program PingPong is coded in the file
"GNAT.Sockets.ads " which deals with both server and client code.

Like I say KNOW your compiler and its packages That way you might be
able to skip spending time seaching the internet or books.


In <0baa592d-1291-4298-90e3-88ca85a476a8(a)k13g2000hse.googlegroups.com>, "snoopysalive(a)googlemail.com" <snoopysalive(a)googlemail.com> writes:
>Come on guys, stop arguing. In the end, I've found a solution:
>
>-----------------------------------------------------------------------
>with Ada.Text_IO,
> Ada.Exceptions,
> Ada.Streams,
> Ada.Unchecked_Deallocation,
> GNAT.Sockets;
>use Ada.Text_IO,
> Ada.Exceptions,
> Ada.Streams,
> GNAT.Sockets;
>
>procedure IP_Server is
>
> BUFFER_SIZE : constant Positive := 1024;
>
> type String_Access is access all String;
>
> procedure Free is new Ada.Unchecked_Deallocation
> (String, String_Access);
>
> CRLF : constant String := ASCII.CR & ASCII.LF;
> Host : constant String := "localhost";
> Port : Port_Type := 7777;
>
> Address : Sock_Addr_Type;
> Server : Socket_Type;
> Client : Socket_Type;
> Channel : Stream_Access;
>
> Data : Stream_Element_Array (1..1);
> Offset : Stream_Element_Count;
>
> Buffer : String_Access := new String (1..BUFFER_SIZE);
> Cnt : Natural := 0;
>
> Test : Float := 0.0;
>
>begin -- IP_Server
> Initialize;
>
> Address.Addr := Addresses (Get_Host_By_Name (Host), 1);
> Address.Port := Port;
>
> Create_Socket (Server);
> Set_Socket_Option (Server, Socket_Level, (Reuse_Address, True));
> Bind_Socket (Server, Address);
> Listen_Socket (Server);
> Accept_Socket (Server, Client, Address);
> Channel := Stream (Client);
>
> Cnt := 0;
> loop
> Read (Channel.all, Data (1..1), Offset);
> if Character'Val (Data (1)) = ASCII.CR or
> Character'Val (Data (1)) = ASCII.LF or
> Character'Val (Data (1)) = ASCII.NUL or
> Offset = 0 then
> exit;
> else
> Cnt := Cnt + 1;
> Buffer.all (Cnt) := Character'Val (Data (1));
> end if;
> end loop;
> -- Read values from client-stream character by character.
> -- Reading should be stopped when Windows-linefeed or
> -- NULL was found, because telnet seams to be sending
> -- strings in a Windows-like format including the
> -- terminating \0-character known from C-strings.
>
> declare
> Old : String_Access := Buffer;
> begin
> Buffer := new String'(Buffer (1..Cnt));
> Free (Old);
> end;
> -- The buffer-size of Str is 1024 elements. It's necessary
> -- to create a new String containing only relevant characters
> -- for being able to process the message further.
>
> declare
> Pong : String := "pong" & CRLF;
> O : Stream_Element_Array (1..Pong'length);
> begin
> if Buffer.all = "ping" then
> for I in Pong'range loop
> O (Stream_Element_Offset (I)) := Character'Pos (Pong (I));
> end loop;
> Write (Channel.all, O);
> end if;
> end;
> -- If Buffer's message equals "ping" the server will
> -- send "pong" to the client. "pong" must be casted
> -- from String to Stream_Element_Array first.
>
> Close_Socket (Client);
> Close_Socket (Server);
>
> Finalize;
>
>exception when E : Socket_Error =>
> Put_Line (Standard_Error, "Socket_Error => " & Exception_Message
>(E));
>
>end IP_Server;
>-----------------------------------------------------------------------------------
>
>Thanks to the thread under http://groups.google.com/group/comp.lang.ada/browse_thread/thread/c58b7bd180ea81b2
>I found out how to read character by character from the client.
>However, it's not very comfortable to cast the echo-string manually
>but it's better than not being able to communicate with telnet or
>other C-based clients.
>
>Bye,
>Matthias