简单的unix域套接字服务器

时间:2015-04-12 18:38:24

标签: haskell unix-socket

我是尝试使用Unix套接字进行编程的新手,并努力让简单的服务器正常工作。我喜欢这样保持运行并打印收到的消息,而是打印出第一条消息然后退出。取决于networkbytestring

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

我认为无论如何我对数据报套接字感兴趣,但是如果有人想向我解释这些内容,我会将其保留为开放状态。

1 个答案:

答案 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