Почему System.Timeout в Haskell не работает для сокетов? - PullRequest
0 голосов
/ 13 января 2019

Я пытаюсь прослушать дейтаграммы UDP всего за 3 секунды в Haskell. Я написал некоторый код, но я не уверен, почему он не работает. Я установил тайм-аут на 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, по-видимому, блокируют, но в действительности они этого не делают, потому что во время выполнения система использует механизмы планирования, такие как select (2), для выполнения асинхронного ввода-вывода Таким образом, с помощью этого комбинатора можно прервать стандартный ввод-вывод сокетов или файловый ввод-вывод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...