【问题标题】:Haskell tcp server, fd is too big errorHaskell tcp server, fd is too big error
【发布时间】:2017-09-09 17:48:05
【问题描述】:

我一直在尝试为 Go 客户端编写 Haskell 服务器。对于 Haskell TCP 服务器,我只是使用Network.Socket。每当我尝试运行 hWaitForInput 时,都会收到此错误:

fdReady: fd is too big.

这是服务器代码-

connHandler :: (Socket, SockAddr) -> IO()
connHandler (sock, _) = do
  putStrLn "Starting Handler"
  handle <- socketToHandle sock ReadWriteMode
  hSetBuffering handle LineBuffering
  hPutStrLn handle "Hello Client!"
  putStrLn "Waiting for Input"
  success <- hWaitForInput handle (1000*10)
  putStrLn "Wait done"
  if success
      then do
          putStrLn "Client timed out"
      else do
          msg <- hGetLine handle
          putStrLn msg
  hClose handle

Go 客户端正在接收并打印服务器的消息(“Hello Client!”),但 Haskell 服务器在打印“Waiting for Input”后立即抛出错误

【问题讨论】:

    标签: sockets haskell tcp


    【解决方案1】:

    作为替代/解决方法,您可以尝试在一个线程中读取一行并在另一个线程中读取计时器。

    putStrLn "Waiting for Input"
    msgMVar <- newEmptyMVar
    tid <- forkIO $ hGetLine handle >>= putMVar msgMVar
    maybeExn <- waitTimeout tid (1000*10)
    case maybeExn of
        Nothing -> do
            killThread tid
            putStrLn "Client timed out"
        Just (Just _) ->
            putStrLn "Exception"
        _ -> do
            msg <- takeMVar msgMVar
            putStrLn msg
    hClose handle
    

    这确实与您的代码具有不同的行为(可以在读取一行的过程中超时)(如果可以读取单个字节,则永远不会超时,即使该行不完整)。

    【讨论】:

    • 我想知道杀死正在执行hGetLine 的线程是否可以在Windows 上工作。正如this question 中所述,我目前无法执行此操作。
    【解决方案2】:

    你没有做错任何事。您看到的特定错误消息仅显示在 Windows 上运行的 GHC >=8.0.2 并表示内部 GHC 函数fdReady 中的错误/限制,他们试图在非 Windows 架构上解决但已离开在 Windows 上未修复。 (不过,不要太嫉妒——非 Windows 架构上的“修复”目前已被破坏并崩溃。)尝试早期版本的 GHC 可能无济于事——它仍然会导致错误,但是错误信息会有所不同。

    问题出在:在 Windows 上,内部函数 fdReady 使用 select() 系统调用来轮询套接字的文件描述符,而 select 被限制为它可以轮询的文件描述符的某个最大数值。看起来这个值的 Windows 默认值非常低(64),但可以在编译时增加(不幸的是,编译 GHC 的时间,而不是 GHC 编译程序的时间)。

    如果添加行:

    hShow handle >>= putStrLn
    

    就在您的hWaitForInput 之前,您应该会看到为套接字打印的一些调试信息,包括类似loc=&lt;socket: nnn&gt; 的内容,其中nnn 是文件描述符。这可以帮助您验证您看到的是大于 64 的文件描述符导致了问题。

    如果是这种情况,我建议您提交 GHC 错误,看看是否可以修复它。

    【讨论】:

    • 我只是opened a bug。让我们看看会发生什么......
    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-12
    • 2022-06-28
    • 2022-11-29
    相关资源
    最近更新 更多