packages feed

network-light-0.1.0.6: tests/unittests/so-reuseaddr-churn/Server.hs

module Server where

import System.Environment
import System.IO
import System.Network

port :: Int
port = 9933

-- One churn cycle: bind a fresh socket to the same port, accept exactly
-- one connection, and actively close it from our end (the side that
-- closes first is the side that lands in TIME_WAIT). Without
-- SO_REUSEADDR the next iteration's bind fails with EADDRINUSE while
-- that TIME_WAIT entry is still around.
churn :: Int -> IO ()
churn i = do
    sfd <- socket AF_INET SOCK_STREAM
    setsocketopt sfd SO_REUSEADDR 1
    bind sfd (mkSockAddr port Nothing)
    listen sfd 1

    putStrLn ("READY_" ++ show i)
    hFlush stdout

    (afd, _) <- accept sfd
    close afd
    close sfd

main :: IO ()
main = do
    [nStr] <- getArgs
    mapM_ churn [1 .. (read nStr :: Int)]
    putStrLn "SERVER_DONE"
    hFlush stdout