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
。懒惰的版本工作正常,但严格的版本似乎根本没有收到任何输出。有什么想法吗?
答案 0 :(得分:4)
我猜它与有问题的两个hGetContents
函数的不同行为(懒惰版本与严格版本)有关。
The strict version&#34;将句柄的全部内容严格地读入ByteString。&#34;但是您尝试从流中读取内容,因此永远不会遇到EOF
。
与the lazy version的行为进行比较:
将整个句柄内容懒洋洋地读入
ByteString
。使用默认的块大小按需读取块。一旦遇到EOF,手柄就会关闭。