ByteString socket真的很奇怪

时间:2017-01-28 22:18:31

标签: haskell

ByteString套接字编程我遇到了一个奇怪的问题。我已将问题最小化到以下简短脚本:

-- ByteString.hs
{-# LANGUAGE OverloadedStrings #-}
import Network.Socket hiding (send, sendTo, recv, recvFrom)
import Network.Socket.ByteString
import Network.BSD
import System.IO
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as C8

connectMud :: HostName
           -> String
           -> IO Handle
connectMud hostname port = do
          addrinfos <- getAddrInfo Nothing (Just hostname) (Just port)
          let serveraddr = head addrinfos
          sock <- socket (addrFamily serveraddr) Stream defaultProtocol
          setSocketOption sock KeepAlive 1
          connect sock (addrAddress serveraddr)
          h <- socketToHandle sock ReadWriteMode
          hSetBuffering h (BlockBuffering Nothing)
          return  h

main:: IO ()
main =
     C8.putStrLn "connecting, please wait" >> connectMud "aardwolf.org" "4000"
     >>= BS.hGetContents >>= C8.putStrLn

--ByteString_Lazy.hs
{-# LANGUAGE OverloadedStrings #-}
import Network.Socket hiding (send, sendTo, recv, recvFrom)
import Network.Socket.ByteString
import Network.BSD
import System.IO
import qualified Data.ByteString.Lazy as BS
import qualified Data.ByteString.Lazy.Char8 as C8

connectMud :: HostName
           -> String
           -> IO Handle
connectMud hostname port = do
          addrinfos <- getAddrInfo Nothing (Just hostname) (Just port)
          let serveraddr = head addrinfos
          sock <- socket (addrFamily serveraddr) Stream defaultProtocol
          setSocketOption sock KeepAlive 1
          connect sock (addrAddress serveraddr)
          h <- socketToHandle sock ReadWriteMode
          hSetBuffering h (BlockBuffering Nothing)
          return  h

main:: IO ()
main =
     C8.putStrLn "connecting, please wait" >> connectMud "aardwolf.org" "4000"
     >>= BS.hGetContents >>= C8.putStrLn

这两个短脚本之间的唯一区别是一个使用Data.ByteString而另一个Data.ByteString.Lazy。懒惰的版本工作正常,但严格的版本似乎根本没有收到任何输出。有什么想法吗?

1 个答案:

答案 0 :(得分:4)

我猜它与有问题的两个hGetContents函数的不同行为(懒惰版本与严格版本)有关。

The strict version&#34;将句柄的全部内容严格地读入ByteString。&#34;但是您尝试从流中读取内容,因此永远不会遇到EOF

the lazy version的行为进行比较:

  

将整个句柄内容懒洋洋地读入ByteString。使用默认的块大小按需读取块。

     

一旦遇到EOF,手柄就会关闭。