我有一个Haskell
程序,可以从套接字获取所有输入并进行打印。
main = withSocketsDo $ do
sock <- listenOn $ PortNumber 5002
netLoop sock
netLoop sock = do
(h,_,_) <- accept sock
hSetBuffering h NoBuffering
forkIO $ workLoop h
netLoop sock
workLoop :: Handle -> IO ()
workLoop h = do
str <- hGetContents h
putStr str
--do any work
但是问题是这种解决方案正在关闭一个套接字,但是我想将计算结果写到同一套接字上。
但是,如果我尝试使用
hGetLine
而不是hGetContents
,则会遇到一些奇怪的行为。在按Ctrl-C之前,我的程序什么也不显示,然后看到发送的网络数据的第一行。我建议这种行为与延迟执行有关,但是为什么hGetContents可以按预期工作而hGetLine却不能工作? 最佳答案
如果要使用LineBuffering
逐行读取,则需要使用hGetLine
。我明白了
import Network
import System.IO
import Control.Concurrent
main :: IO ()
main = withSocketsDo $ do
sock <- listenOn $ PortNumber 5002
netLoop sock
netLoop :: Socket -> IO ()
netLoop sock = do
putStrLn "Accepting socket"
(h,_,_) <- accept sock
putStrLn "Accepted socket"
hSetBuffering h LineBuffering
putStrLn "Starting workLoop"
forkIO $ workLoop h
netLoop sock
workLoop :: Handle -> IO ()
workLoop h = do
putStrLn "workLoop started"
str <- hGetLine h
putStrLn $ "Read text: " ++ str
-- do any work
并使用python脚本对其进行了测试
import socket
s = socket()
s.connect(('127.0.0.1', 5002))
s.send('testing\n')
s.close()
我得到了输出
Accepting socket
Accepted socket
Starting workLoop
workLoop started
Accepting socket
Read text: testing
如果我将其更改为
NoBuffering
和hGetContents
,也会得到相同的行为