socket-0.5.0.0: tests/UDP.hs
{-# LANGUAGE OverloadedStrings #-}
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 as Inet
import System.Socket.Family.Inet6 as Inet6
import System.Exit
main :: IO ()
main = do
test "Inet" (undefined :: Socket Inet Datagram UDP) localhost
test "Inet6" (undefined :: Socket Inet6 Datagram UDP) localhost6
-- Test stateless sockets (i.e. UDP).
test :: (Family f, Type t, Protocol p) => String -> Socket f t p -> SocketAddress f -> IO ()
test inet dummy addr = do
server <- socket `asTypeOf` return dummy `onException` p 1
client <- socket `asTypeOf` return dummy `onException` p 2
bind server addr `onException` p 4
((msg,peeraddr),_) <- concurrently
( do
receiveFrom server 4096 mempty `onException` p 5
)
( do
-- This is a race condition:
-- The server must listen before the client sends his msg or the packt goes
-- to nirvana. Still, a second here should be enough. If not, there's
-- something wrong worth investigating.
threadDelay 1000000
sendTo client helloWorld mempty addr `onException` p 6
)
when (msg /= helloWorld) $ e 8
close client `onException` p 10
close server `onException` p 11
where
helloWorld = "Hello world!"
e i = error (inet ++ ": " ++ show i)
p i = print (inet ++ ": " ++ show i)
localhost :: SocketAddressInet
localhost =
SocketAddressInet
{ Inet.port = 7777
, Inet.address = Inet.loopback
}
localhost6 :: SocketAddressInet6
localhost6 =
SocketAddressInet6
{ Inet6.port = 7777
, Inet6.address = Inet6.loopback
, Inet6.flowInfo = mempty
, Inet6.scopeId = 0
}