module TCPPingServer
( runServer
) where

import Network.Socket
import Control.Exception
import Control.Concurrent

runServer :: IO ()
runServer = do
    sock <- socket AF_INET Stream 0
    setSocketOption sock ReuseAddr 1
    bindSocket sock $ SockAddrInet 4242 iNADDR_ANY
    listen sock 2
    serverLoop sock

serverLoop :: Socket -> IO ()
serverLoop sock = do
    conn <- accept sock
    forkIO $ serve conn
    serverLoop sock
 
serve :: (Socket, SockAddr) -> IO ()
serve (sock, addr) = do
    req <- try $ recv sock 1024 :: IO (Either IOException String)
    case req of
        Left ex -> do
          putStrLn "connection closed"
          sClose sock
        Right req -> do
            if req == "ping!"
                then do
                    putStrLn req
                    send sock "pong!"
                else return 0 
            serve (sock, addr)
