[Haskell-cafe] How to flush with IterIO in echo server

John Ky newhoggy at gmail.com
Wed Jun 29 13:13:47 CEST 2011


Hi Haskell Cafe,

I've written an echo server using just sockets:

import Control.Concurrent
import Control.Exception
import Control.Monad
import Network
import Offsync.Data
import System.IO
import System.IO.Error (isEOFError)

main = withSocketsDo $ do
  sListen <- listenOn (PortNumber 8000)
  putStrLn "Listening on Port 8000"
  forkIO $ forever $ do
    (sSession, hostname, port) <- accept sListen
    putStrLn ("Connected to " ++ hostname ++ ":" ++ show port)
    forkIO $ echoLines sSession
  putStrLn "Press <CTRL-D> to quit."
  exitOnCtrlD

echoLines h = try (hGetLine h) >>= either
  (\e -> do { hClose h; if isEOFError e then print e else ioError e})
  (\l -> do { hPutStrLn h l; hFlush h; echoLines h})

exitOnCtrlD = try getLine >>= either
  (\e -> unless (isEOFError e) $ ioError e)
  (const exitOnCtrlD)


When I send text to it, it will echo it back immediately after my newline.

I then modified it to user IterIO:

import Control.Concurrent
import Control.Exception
import Control.Monad
import Control.Monad.Trans
import Data.IterIO
import Data.IterIO.Inum
import Network
import System.IO
import System.IO.Error (isEOFError)
import qualified Data.ByteString.Lazy as L

iterHandle' :: (MonadIO m) => Handle -> IO (Iter L.ByteString m (), Onum
L.ByteString m a)
iterHandle' = iterHandle

main = withSocketsDo $ do
  sListen <- listenOn (PortNumber 8000)
  putStrLn "Listening on Port 8000"
  forkIO $ forever $ do
    (sSession, hostname, port) <- accept sListen
    putStrLn ("Connected to " ++ hostname ++ ":" ++ show port)
    forkIO $ do
      (iter, enum) <- iterHandle' sSession
      enum |$ iter
      return ()
  putStrLn "Press <CTRL-D> to quit."
  exitOnCtrlD

exitOnCtrlD = try getLine >>= either
  (\e -> unless (isEOFError e) $ ioError e)
  (const exitOnCtrlD)


It works, however it doesn't send anything back to me until end of file.

I fixed that problem with my sockets version by flushing after each line,
but I don't know if IterIO will let me flush on every newline.

Any ideas?

Cheers,

-John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110629/9a6038fc/attachment.htm>


More information about the Haskell-Cafe mailing list