On 2015-11-13 21:41, Jan Synáček wrote:
On Fri, Nov 13, 2015 at 4:51 PM, Mark H Weaver <m...@netris.org> wrote:
Jan Synáček <jan.syna...@gmail.com> writes:
> On Sun, Nov 8, 2015 at 12:49 AM, Andreas Rottmann <a.rottm...@gmx.at>
> wrote:
>
> Also note that if there's no requirement to actually implement
> this in
> C, there's `fdes->inport' and `fdes->outport' on the Scheme level,
> so
> something like the following would be analogous to the C example
> code
> posted:
>
> (import (ice-9 binary-ports))
>
> (define (process-fd fd)
> (let ((port (fdes->inport fd)))
> (display "read: ")
> (display (get-bytevector-n port 100))
> (display "\n")))
>
> (process-fd (acquire-valid-fd))
>
>
> This is something very similar that I ended up with. Just instead of
> get-byte-vector, I used read-string!/partial.
I would advise against using 'read-string!/partial' or any of the
procedures in (ice-9 rw). This is a vestigial module from Guile 1.8
when strings were arrays of bytes, which they no longer are. We
should
probably mark them as deprecated.
For one thing, when we switch to using UTF-8 as the internal string
encoding, it will not be possible to keep 'read-string!/partial'
efficient. It will necessarily have to do an encoding conversion.
In Guile 2+, I would advise using byte vectors when working with
binary
data. Portions of these can be converted to strings with a given
encoding if desired. I might be able to give better advice if I knew
more about what you are doing here.
Regards,
Mark
I have an open fd to a unix socket and I want to read data from it. I
know that the data is going to be only strings, but I don't know the
length in advance.
Do you know a delimiter? maybe it's the null char?
TCP is stream oriented, it's not structured at this layer into messages
or segments. You need some knowledge about the byte stream to be able to
split it into different meaningful piece for the upper layer.
In Python the socket.recv method returns bytestring but still you have
to parse
to bytestring to make sure the delimiter is not in the middle of the
string. What
I mean is that in theory you might socket.recv the end of an application
level message
and the beginning of another using the same call.
Otherwise said, the only thing that could make sens for a (recv)
procedure is
to return the full content of the inbound network buffer for the given
socket
as a bytevector but it will still require work to to make things work...
The good thing about using read-string!/partial is,
that I don't have to specify how many bytes I want to read and it does
the right thing. If you point me to a better direction, I'll be
grateful. I came up with:
(for-each (lambda (fd)
(let* ((buf (make-string 4096)))
(read-string!/partial buf (fdes->inport fd))
(format #t "fd[~a]: ~a" fd buf) (newline)))
fds)
Have a look at the implementation. IMO the solution is to build a loop
with
(read-char) [1] looking for the *end char* to stop the loop.
[1]
https://www.gnu.org/software/guile/manual/html_node/Reading.html#index-read_002dchar