Haskell 他为什么不回来?
我正在使用Haskell的Haskell 他为什么不回来?,haskell,client-server,handle,Haskell,Client Server,Handle,我正在使用Haskell的网络库创建一个简单的聊天服务器。服务器必须做两件事: 每隔n滴答声向当前连接的所有客户端广播一条消息 从客户端接收发送到服务器的任何消息 服务器和客户端定义为 data Server = Server { sSocket :: Socket, sPort :: Port, sClients :: MVar (Set.Set ClientAddress) } newtype ClientAddress = ClientAddress (Handle,
网络
库创建一个简单的聊天服务器。服务器必须做两件事:
- 每隔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
我遇到的问题是,从客户端接收消息似乎会阻塞。我通过检查句柄是否包含内容来接收消息
serve :: ClientAddress -> IO ()
serve (ClientAddress (handle, host, port)) = do
b <- hIsEOF handle
putStrLn $ show $ b -- <-- It never makes it this far...
service::ClientAddress->IO()
服务(客户端地址(句柄、主机、端口))=do
b在他的
中,我发现:
注意:hIsEOF可能会阻塞,因为它必须尝试从
流来确定是否还有更多的数据要读取
我没想到会这样。我想知道hReady
或hGetBufNonBlocking
是否更好?我从未在Haskell中尝试过整个非阻塞IO位。在hIsEOF
中,我发现了以下内容:
注意:hIsEOF可能会阻塞,因为它必须尝试从
流来确定是否还有更多的数据要读取
我没想到会这样。我想知道
hReady
或hGetBufNonBlocking
是否更好?我从未在Haskell中尝试过整个非阻塞IO位。您能捕获并打印出异常吗?您可以使用Control.Exception.try
来执行此操作,方法是:try(hIsEOF handle)::IO(SomeException Bool)
它不会通过允许我打印任何内容的尝试。如果我在try…
之前放置一个print语句,它会显示,但不会在之后显示。您链接的文档确实会说“注意:hIsEOF可能会阻塞,因为它必须尝试从流中读取,以确定是否还有更多的数据要读取。”如果try
阻塞,则这意味着它不是例外try
设计用于在出现异常时立即返回。这表明@rjanJohansen是正确的,它正在阻止从流中读取。您能捕获并打印出异常吗?您可以使用Control.Exception.try
来执行此操作,方法是:try(hIsEOF handle)::IO(SomeException Bool)
它不会通过允许我打印任何内容的尝试。如果我在try…
之前放置一个print语句,它会显示,但不会在之后显示。您链接的文档确实会说“注意:hIsEOF可能会阻塞,因为它必须尝试从流中读取,以确定是否还有更多的数据要读取。”如果try
阻塞,则这意味着它不是例外try
设计用于在出现异常时立即返回。这表明@rjanJohansen是正确的,它在读流时阻塞了。谢谢,你们三个是正确的,它阻塞了。谢谢,你们三个是正确的,它阻塞了。
serve :: ClientAddress -> IO ()
serve (ClientAddress (handle, host, port)) = do
b <- hIsEOF handle
putStrLn $ show $ b -- <-- It never makes it this far...