Car*_*ate 2 networking buffer haskell
我正在阅读本教程:http: //www.catonmat.net/blog/simple-haskell-tcp-server/ 了解Haskell网络模块的基础知识.他写了一个名为sockHandler的小函数:
sockHandler :: Socket -> IO ()
sockHandler sock = do
(handle, _, _) <- accept sock
hSetBuffering handle NoBuffering
forkIO $ commandProcessor handle
sockHandler sock
Run Code Online (Sandbox Code Playgroud)
接受连接,并将其分配给新线程.在打破代码的同时,他说:
"接下来我们使用hSetBuffering将客户端套接字句柄的缓冲模式更改为NoBuffering,因此我们没有缓冲惊喜."
但是没有详细说明这一点.他在谈论什么惊喜?我谷歌了,看到了一些安全文章(我猜测与被拦截的缓存有关),但似乎与本教程的内容没什么关系.
有什么问题?我想到了,但我认为我没有足够的网络经验来填补空白.
谢谢.
为了便于说明,假设协议允许服务器向客户端查询某些信息,例如(以下是愚蠢的例子)
hPutStr sock "Please choose between A or B"
choice <- hGetLine sock
case decode choice of
Just A -> handleA
Just B -> handleB
Nothing -> protocolError
Run Code Online (Sandbox Code Playgroud)
一切看起来都很好......但服务器似乎挂了.为什么?这是因为消息并非真正通过网络发送hPutStr,而只是插入本地缓冲区.因此,另一端永远不会收到查询,因此不会回复,导致服务器卡在其读取中.
这里的解决方案是hFlush sock在读取之前插入.这必须手动插入"右"点,并且容易出错.更懒的选择是完全禁用缓冲 - 这更安全,尽管它会严重影响性能.