I have a program in Haskell
that get all input from socket and print it.
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
But the problem is that this solution is closing a socket, but I want to write out the results of computation to the same socket.
But if I try to use hGetLine
instead hGetContents
I faced with some strange behaviour. My program show nothing until I press Ctrl-C, and then I see the first line of my network data sended. I suggest that this behaviour related with lasy execution, but why hGetContents works as expected and hGetLine not?
You need to use LineBuffering
if you want to read line-by-line using hGetLine
. I got it working with
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
And tested it using the python script
import socket
s = socket()
s.connect(('127.0.0.1', 5002))
s.send('testing\n')
s.close()
And I got the output
Accepting socket
Accepted socket
Starting workLoop
workLoop started
Accepting socket
Read text: testing
And I get the same behavior if I change it to NoBuffering
and hGetContents
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With