首页 > 解决方案 > 为什么 Haskell 中的 System.Timeout 不适用于套接字?

问题描述

我试图在 Haskell 中只听 3 秒钟的 UDP 数据报。我写了一些代码,但我不确定为什么它不起作用。我将超时设置为 3 秒,但它只是永远等待并且不会阻塞

import Control.Concurrent  as CC  (forkIO, threadDelay, killThread)
import qualified Data.ByteString.Char8 as C
import Network.Socket 
import Network.Socket.ByteString as B
import Data.IORef
import Control.Monad            (forever)
import System.Timeout

receiveDatagram = do 
  ack <- newIORef (0 :: Int) 
  addrinfos <- getAddrInfo Nothing (Just "127.0.0.1") (Just "7001")
  let serveraddr = head addrinfos
  sock <- socket (addrFamily serveraddr) Datagram defaultProtocol
  bind sock (addrAddress serveraddr)
  print "starting"
  tmp <- timeout 3000000 (do
    (msg, addr) <- B.recvFrom sock 1024
    close sock
    writeIORef ack 1
    print msg
    )
  case tmp of 
    Nothing -> close sock
    _       -> print "something else"
  print "timeout done"

状态的文档timeout

hGetBuf、hPutBuf、Network.Socket.accept 或 hWaitForInput 等标准 I/O 函数看起来是阻塞的,但实际上并非如此,因为运行时系统使用诸如 select(2) 之类的调度机制来执行异步 I/O,所以它可以使用此组合器中断标准套接字 I/O 或文件 I/O。

标签: socketshaskellnetworkingtimeout

解决方案


推荐阅读