guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Unix Domain Sockets and (write) (read)


From: Alex Sassmannshausen
Subject: Unix Domain Sockets and (write) (read)
Date: Wed, 03 Jul 2013 00:31:23 +0200

Hello,

I'm playing around with interprocess communication through Unix Domain
Sockets and guile. I've got 2 programs: a 'server' and a 'client'. I'm
trying to send s-expressions from the one to the other using the 'read'
and 'write' procedures.

I've got the sockets set up currently:

On the server:  
(let ((s (socket PF_UNIX SOCK_STREAM 0))
      (sock-addr (make-socket-address AF_UNIX "/path/to/socket")))

   (setsockopt s SOL_SOCKET SO_REUSEADDR 1)
   (bind s sock-addr)
   (listen s 5)

   (let* ((client-connection (accept s))
          (client-details (cdr client-connection))
          (client (car client-connection)))
          (simple-format #t "Got new client connection:")
          (newline)
          (simple-format #t "writing message")
          (newline)
          (write 'test-comms client)
          (simple-format #t "Written. Now waiting for response.")
          (newline)
          (read) ; to make the server wait for standard input
          (close client)))

On the client:
(let* ((s (socket PF_UNIX SOCK_STREAM 0))
       (path (string-append "/path/to/socket"))
       (address (make-socket-address AF_UNIX path)))

       (connect s address)
       (display (read s))
       (close s))

- I first run the server, which sits and wait for client connections.
- I run the client, which connects to the server
- The server accepts, writes a message to client 
- Then it moves on to the (read) stage
- The client now simply reads from s in perpetuity

When I finally provide some input and a newline in std input for the
server, it closes the connection to the client, and at this stage the
client finally returns with its reading from the socket.

My question is simply: is this supposed to happen? Would I somehow need
to close and re-open the socket to have a two-way conversation between
the client and the server (e.g. client writes request, closes the socket,
server reads from socket, evaluates, client re-connects, server provides
response)?

The documentation suggests that read simply reads one s-expression and
returns (guile 2 > API > REPL > Scheme Read):
     Read an s-expression from the input port PORT, or from the current
     input port if PORT is not specified.  Any whitespace before the
     next token is discarded.

When I write several s-expressions to the unix port and then disconnect,
the client does indeed read one s-expression at a time.

Any ideas or comments as to what is going on?

Best wishes,

Alex

PS: just noticed that changing the client socket from SOCK_STREAM to
SOCK_DGRAM allows the client to read all but the final s-expression from
the socket — so it hangs on the last one. Again, closing the socket
server-side then returns the last s-expression client-side.
This wouldn't resolve the 2 way communications issue as SOCK_DGRAM does
not seem to work for a server: (listen) returns an error with SOCK_DGRAM
server-side. 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]