Haskell ByteString套接字存在非常奇怪的问题

Haskell ByteString套接字存在非常奇怪的问题,haskell,Haskell,我在ByteStringsocket编程方面遇到了一个奇怪的问题。我已将问题最小化为以下简短脚本: -- ByteString.hs {-# LANGUAGE OverloadedStrings #-} import Network.Socket hiding (send, sendTo, recv, recvFrom) import Network.Socket.ByteString import Network.BSD import System.IO import qualified Da

我在
ByteString
socket编程方面遇到了一个奇怪的问题。我已将问题最小化为以下简短脚本:

-- 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.hs
{-#语言重载字符串}
导入网络套接字隐藏(发送、发送到、recv、recvFrom)
导入Network.Socket.ByteString
导入网络.BSD
导入系统.IO
将符合条件的数据.ByteString作为BS导入
将符合条件的Data.ByteString.Char8导入为C8
connectMud::主机名
->串
->IO句柄
connectMud主机名端口=do
addrinfos>=BS.hGetContents>>=C8.putStrLn

-ByteString\u Lazy.hs
{-#语言重载字符串}
导入网络套接字隐藏(发送、发送到、recv、recvFrom)
导入Network.Socket.ByteString
导入网络.BSD
导入系统.IO
将限定数据.ByteString.Lazy导入为BS
将限定的Data.ByteString.Lazy.Char8导入为C8
connectMud::主机名
->串
->IO句柄
connectMud主机名端口=do
addrinfos>=BS.hGetContents>>=C8.putStrLn

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

我想这与所讨论的两个
hGetContents
函数(惰性版本和严格版本)的不同行为有关

“将句柄的全部内容严格读取到ByteString中。”但您尝试从流中读取,因此永远不会遇到
EOF

与以下行为相比:

通过testring将整个句柄内容惰性地读入
中。块是按需读取的,使用默认块大小

一旦遇到EOF,句柄将关闭


我猜这与所讨论的两个
hGetContents
函数(惰性版本和严格版本)的不同行为有关

“将句柄的全部内容严格读取到ByteString中。”但您尝试从流中读取,因此永远不会遇到
EOF

与以下行为相比:

通过testring将整个句柄内容惰性地读入
中。块是按需读取的,使用默认块大小

一旦遇到EOF,句柄将关闭


谢谢真是个陷阱。懒惰的人工作更努力。另外,为了让我的程序正常工作,我不得不将hSetBuffering改为“NoBuffering”。谢谢!真是个陷阱。懒惰的人工作更努力。我还必须将hSetBuffering改为“NoBuffering”,这样我的程序才能正常工作。
--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