[英]Why does hIsEOF not return?
我正在使用Haskell的Network
庫創建一個簡單的聊天服務器。 服務器必須做兩件事:
服務器和客戶端定義為
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可能會阻塞,因為它必須嘗試從流中讀取以確定是否還有更多數據要讀取。
我不會想到這一點。 我想知道hReady
或hGetBufNonBlocking
是否更好? 我從來沒有嘗試過Haskell中的整個非阻塞IO位。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.