socket-0.4.0.0: tests/TCP.hs
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, TypeFamilies #-}
module Main where
import Data.Monoid
import Control.Monad
import Control.Exception
import Control.Concurrent
import Control.Concurrent.Async
import System.Socket
import System.Socket.Family.INET
import System.Socket.Family.INET6
import System.Exit
main :: IO ()
main = do
test "test0001.01" $ test0001 (undefined :: Socket INET STREAM TCP) localhost
test "test0001.02" $ test0001 (undefined :: Socket INET6 STREAM TCP) localhost6
-- Test send and receive on connection oriented sockets (i.e. TCP).
test0001 :: (Family f, Type t, Protocol p) => Socket f t p -> SockAddr f -> IO (Either String String)
test0001 dummy addr =
bracket
( do server <- socket `asTypeOf` return dummy `onException` print "E01"
client <- socket `asTypeOf` return dummy `onException` print "E02"
return (server, client)
)
(\(server,client)-> do
close server `onException` print "E03"
close client `onException` print "E04"
)
(\(server,client)-> do
setSockOpt server (SO_REUSEADDR True) `onException` print "E05"
bind server addr `onException` print "E06"
listen server 5 `onException` print "E07"
serverRecv <- async $ do
(peerSock, peerAddr) <- accept server `onException` print "E08"
recv peerSock 4096 mempty `onException` print "E09"
connect client addr `onException` print "E11"
send client helloWorld mempty `onException` print "E12"
msg <- wait serverRecv `onException` print "E13"
close server `onException` print "E14"
close client `onException` print "E15"
if (msg /= helloWorld)
then return (Left "Received message was bogus.")
else return (Right "")
)
where
helloWorld = "Hello world!"
localhost :: SockAddrIn
localhost =
SockAddrIn
{ sinPort = 7777
, sinAddr = inaddrLOOPBACK
}
localhost6 :: SockAddrIn6
localhost6 =
SockAddrIn6
{ sin6Port = 7777
, sin6Addr = in6addrLOOPBACK
, sin6Flowinfo = 0
, sin6ScopeId = 0
}
test :: String -> IO (Either String String) -> IO ()
test n t = do
putStr ("Test " ++ show n ++ ": ")
catch
( do r <- t
case r of
Left x -> putStr "FAIL " >> putStrLn x >> exitFailure
Right x -> putStr "OK " >> putStrLn x
)
(\e-> putStr "EXCP " >> putStrLn (show (e :: SomeException)) >> exitFailure)