2017-01-28 2 views
1

私はByteStringソケットプログラミングで奇妙な問題がありました。私は、次の短いスクリプトに問題を最小限に抑えています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 

これら二つの短いスクリプトの唯一の違いは、1がData.ByteString、他方Data.ByteString.Lazyを使用していることです。怠惰なバージョンは正常に動作しますが、厳密なバージョンは全く出力を受け取っていないようです。何かご意見は?

答えて

4

2つのhGetContents関数の異なる動作(遅延バージョンと厳密バージョンの違い)と関係があると思います。

The strict version "ハンドルの全体の内容を厳密にByteStringに読み込みます。"しかし、あなたはストリームから読むことを試みているので、EOFは決して遭遇しません。

the lazy versionの行動と比較する:

はハンドル全体の内容 怠惰 ByteStringにをお読みください。チャンクは、デフォルトのチャンクサイズを使用してオンデマンドで読み込まれます。

EOFが発生すると、ハンドルが閉じます。

+0

ありがとう!どんなキャッチーなの?怠惰なものはもっと頑張ります。また、私のプログラムが正しく動作するためには、 "NoBuffering"にhSetBufferingに変更しなければなりませんでした。 – user2812201