I'm new to trying to program with Unix sockets, and struggling to get a simple server working. I'd like this to stay running and print messages it receives, but instead it prints the first message and exits. Depends on network
, and bytestring
.
module Main where
import Network.Socket hiding (send, sendTo, recv, recvFrom)
import Network.Socket.ByteString
import qualified Data.ByteString.Char8 as C
import Control.Monad
main :: IO ()
main = withSocketsDo $ do
sock <- socket AF_UNIX Stream 0 -- and try UDP?
bind sock (SockAddrUnix "/tmp/test_sock.ipc")
listen sock maxListenQueue -- TODO is maxListenQueue what we want?
(conn, _) <- accept sock
talk conn
close conn
close sock
putStrLn "DONE"
where
talk :: Socket -> IO ()
talk conn =
do msg <- recv conn 1024
unless (C.null msg) $ do
C.putStrLn msg
talk conn
I'm testing with socat
, which I also don't really know how to use:
echo "FOOOOO" | socat - UNIX-CONNECT:/tmp/test_sock.ipc
Any pointers on the haskell code, and what I might be misunderstanding about unix sockets would be helpful.
EDIT Using Datagram
instead of Stream
I'm able to get more or less what I want:
main :: IO () main = withSocketsDo $ do sock <- socket AF_UNIX Datagram 0 -- and try UDP? bind sock (SockAddrUnix "/tmp/test_sock.ipc") -- for Datagram: talk sock close sock putStrLn "DONE"
where
talk :: Socket -> IO ()
talk conn =
do msg <- recv conn 1024
unless (C.null msg) $ do
C.putStrLn msg
talk conn
And I can test successfully with:
echo "FOOOOO" | socat - UNIX-SENDTO:/tmp/test_sock.ipc
I think I'm interested in datagram sockets anyway, but I'll leave this open if anyone wants to explain things to me.