我是尝试使用Unix套接字进行编程的新手,并努力让简单的服务器正常工作。我喜欢这样保持运行并打印收到的消息,而是打印出第一条消息然后退出。取决于network
和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
我正在使用socat
进行测试,我也不知道该如何使用:
echo "FOOOOO" | socat - UNIX-CONNECT:/tmp/test_sock.ipc
关于haskell代码的任何指针,以及我可能对unix套接字的误解都会有所帮助。
编辑使用Datagram
代替Stream
我可以获得更多或更少的内容:
main :: IO() main = withSocketsDo $ do sock&lt; - socket AF_UNIX数据报0 - 并尝试UDP? 绑定袜子(SockAddrUnix&#34; /tmp/test_sock.ipc") - 对于数据报: 说袜子 关闭袜子 putStrLn&#34; DONE&#34;
where
talk :: Socket -> IO ()
talk conn =
do msg <- recv conn 1024
unless (C.null msg) $ do
C.putStrLn msg
talk conn
我可以成功测试:
echo "FOOOOO" | socat - UNIX-SENDTO:/tmp/test_sock.ipc
我认为无论如何我对数据报套接字感兴趣,但是如果有人想向我解释这些内容,我会将其保留为开放状态。
答案 0 :(得分:2)
您的代码仅运行&#34;接受&#34;一次,所以它只能处理一个连接。如果你想处理多个连接,那么&#34;接受&#34;部分必须重复,而不仅仅是&#34; recv&#34;一部分。
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?
go sock
close conn
close sock
putStrLn "DONE"
where
go sock = do
(conn,_) <- accept sock
talk conn
go sock
talk :: Socket -> IO ()
talk conn =
do msg <- recv conn 1024
unless (C.null msg) $ do
C.putStrLn msg
talk conn