module Programs.TcpEchoIterServer where
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
import qualified Data.ByteString.Lazy.Char8 as C
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
hSetBuffering sSession NoBuffering
putStrLn ("Connected to " ++ hostname ++ ":" ++ show port)
forkIO $ do
(iter, enum) <- iterHandle' sSession
enum |$ inumLines .| inumReverse .| inumUnlines .| iter
putStrLn "Press <CTRL-D> to quit."
exitOnCtrlD
iterLines :: (Monad m) => Iter L.ByteString m [L.ByteString]
iterLines = do
line <- lineI
return [line]
iterUnlines :: (Monad m) => Iter [L.ByteString] m L.ByteString
iterUnlines = (L.concat . (++ [C.pack "\n"])) `liftM` dataI
iterReverse :: (Monad m) => Iter [L.ByteString] m [L.ByteString]
iterReverse = do
lines <- dataI
return (map L.reverse lines)
inumLines = mkInum iterLines
inumUnlines = mkInum iterUnlines
inumReverse = mkInum iterReverse
exitOnCtrlD = try getLine >>= either
(\e -> unless (isEOFError e) $ ioError e)
(const exitOnCtrlD)
It all works fine.