How to properly read and write on sockets using Ada?
ada
Solution
GNAT sockets are created blocking, so when you call `Streams.Read` it will read from the socket until
- your Buffer is full; or
- there aren’t yet any more bytes to read; or
- the socket has been closed.
In case 2, the `Read` call blocks until more data arrives. Only in case 3 will you get back an underfull buffer (in your code, `Offset` less than `Buffer’Last`).
If you have multiple clients, any of which could be sending data, you can use `GNAT.Sockets.Check_Selector` to block until one of the client sockets has data to read, and then read from that socket.
As for reading a complete input message, you can read a byte at a time until you reach a terminator (in the case of an HTTP request, that would be a double CR/LF). Of course, you need to agree with the client side what will constitute a terminator.
The answer from @ajb has covered writing.
Problem
Basically, I managed to connect several clients to a single server, but I have a problem reading from the server. I have two tasks (threads): one for reading, and one for writing. - The offset never gets to 0 resulting an infinite loop. How can I print `"Incoming > "` every time there is a new incoming message from server? - And Im not really sure about the buffer size. I tried 1..1024 but nothing get printed until server sends 1024 chars. - is `String'Write` a shortcut for `ada.streams.write`? Writing data ``` String'Write(channel, "Hello client"); --Where channel is Gnat.Sockets.Stream_Access type ``` Reading data from server ``` task body reader_task is Offset : Streams.Stream_Element_Count; Buffer : Streams.Stream_Element_Array (1 .. 1); begin loop Text_IO.put_line("Incoming > "); loop Streams.Read (Channel.All, Buffer, Offset); exit when offset = 0; for I in Buffer'Range loop Text_IO.Put (Character'Val (Buffer (I))); end loop; end loop; end loop; end reader_task; ```