[英]Why does hIsEOF not return?
I am creating a simple chat server using Haskell's Network
library. 我正在使用Haskell的
Network
库创建一个简单的聊天服务器。 The server has to do two things: 服务器必须做两件事:
The server and client are defined as 服务器和客户端定义为
data Server = Server {
sSocket :: Socket,
sPort :: Port,
sClients :: MVar (Set.Set ClientAddress)
}
newtype ClientAddress = ClientAddress (Handle, HostName, PortNumber)
deriving (Show)
A server is constructed by running the following function 通过运行以下函数构造服务器
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
Note that the last two lines fork two different threads: the first for handling client connections and "serving" their messages, and the second for sending server broadcasts to the clients. 请注意,最后两行分叉两个不同的线程:第一个用于处理客户端连接和“提供”其消息,第二个用于将服务器广播发送到客户端。
Broadcasting to the clients works as follows 广播给客户的工作如下
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."
The issue I have, is that receiving messages from the clients seem to block. 我遇到的问题是,从客户端接收消息似乎阻止了。 I receive messages by checking if the handle has contents
我通过检查句柄是否有内容来接收消息
serve :: ClientAddress -> IO ()
serve (ClientAddress (handle, host, port)) = do
b <- hIsEOF handle
putStrLn $ show $ b -- <-- It never makes it this far...
Unfortunately, the code never makes it to the second line to call the putStrLn
. 不幸的是,代码永远不会到第二行调用
putStrLn
。 It seems like hIsEOF
encounters some exception, although the documentation doesn't seem to mention it . 似乎
hIsEOF
遇到了一些例外, 虽然文档似乎没有提到它 。
Why does my code block on hIsEOF
forever? 为什么我的代码
hIsEOF
永久阻止hIsEOF
?
In hIsEOF
's documentation I found the following: 在
hIsEOF
的文档中,我发现了以下内容:
NOTE: hIsEOF may block, because it has to attempt to read from the stream to determine whether there is any more data to be read.
注意:hIsEOF可能会阻塞,因为它必须尝试从流中读取以确定是否还有更多数据要读取。
I wouldn't have expected this. 我不会想到这一点。 I wonder if
hReady
or hGetBufNonBlocking
are any better? 我想知道
hReady
或hGetBufNonBlocking
是否更好? I've never tried the whole non-blocking IO bit in Haskell. 我从来没有尝试过Haskell中的整个非阻塞IO位。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.