簡體   English   中英

為什么hIsEOF不會返回?

[英]Why does hIsEOF not return?

我正在使用Haskell的Network庫創建一個簡單的聊天服務器。 服務器必須做兩件事:

  • n個刻度向所有當前連接的客戶端廣播消息
  • 從發送到服務器的客戶端接收任何消息。

服務器和客戶端定義為

data Server = Server {
  sSocket :: Socket,
  sPort :: Port,
  sClients :: MVar (Set.Set ClientAddress)
  }

newtype ClientAddress = ClientAddress (Handle, HostName, PortNumber) 
                          deriving (Show)

通過運行以下函數構造服務器

startServer :: Port -> IO ThreadId -- 
startServer port = withSocketsDo $ do
  socket  <- listenOn $ PortNumber $ fromIntegral port  
  clients <- newMVar Set.empty
  let server = Server socket port clients
  forkIO $ forever $ do
    client@(handle, host, port) <- accept socket
    modifyMVar_ clients (\cs -> return $ Set.insert (ClientAddress client) cs)
    forkIO $ forever $ serve $ ClientAddress client
  forkIO $ forever $ sendServerUpdates 1000000 server

請注意,最后兩行分叉兩個不同的線程:第一個用於處理客戶端連接和“提供”其消息,第二個用於將服務器廣播發送到客戶端。

廣播給客戶的工作如下

sendServerUpdates :: Microsecond -> Server -> IO ()
sendServerUpdates frequency server = do
  withMVar (sClients server) (mapM_ sendServerUpdate)
  threadDelay frequency

sendServerUpdate :: ClientAddress -> IO ()
sendServerUpdate (ClientAddress (handle, host, port)) = do
  putStrLn "Sending update."

我遇到的問題是,從客戶端接收消息似乎阻止了。 我通過檢查句柄是否有內容來接收消息

serve :: ClientAddress -> IO ()
serve (ClientAddress (handle, host, port)) = do
  b <- hIsEOF handle
  putStrLn $ show $ b -- <-- It never makes it this far...

不幸的是,代碼永遠不會到第二行調用putStrLn 似乎hIsEOF遇到了一些例外, 雖然文檔似乎沒有提到它

為什么我的代碼hIsEOF永久阻止hIsEOF

hIsEOF文檔中,我發現了以下內容:

注意:hIsEOF可能會阻塞,因為它必須嘗試從流中讀取以確定是否還有更多數據要讀取。

我不會想到這一點。 我想知道hReadyhGetBufNonBlocking是否更好? 我從來沒有嘗試過Haskell中的整個非阻塞IO位。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM