client :: (String, Network.PortID) -> IO ()
client addr = do
    to <- hOpen addr
    let ps = (BinaryProtocol to, BinaryProtocol to)

    v1 <- Client.testString ps "bya"
    ThriftTestUtils.clientLog v1

    v2 <- Client.testByte ps 8
    ThriftTestUtils.clientLog $ show v2

    v3 <- Client.testByte ps (-8)
    ThriftTestUtils.clientLog $ show v3

    v4 <- Client.testI32 ps 32
    ThriftTestUtils.clientLog $ show v4

    v5 <- Client.testI32 ps (-32)
    ThriftTestUtils.clientLog $ show v5

    v6 <- Client.testI64 ps 64
    ThriftTestUtils.clientLog $ show v6

    v7 <- Client.testI64 ps (-64)
    ThriftTestUtils.clientLog $ show v7

    v8 <- Client.testDouble ps 3.14
    ThriftTestUtils.clientLog $ show v8

    v9 <- Client.testDouble ps (-3.14)
    ThriftTestUtils.clientLog $ show v9

    v10 <- Client.testMap ps (Map.fromList [(1,1),(2,2),(3,3)])
    ThriftTestUtils.clientLog $ show v10

    v11 <- Client.testStringMap ps (Map.fromList [("a","123"),("a b","with spaces "),("same","same"),("0","numeric key")])
    ThriftTestUtils.clientLog $ show v11

    v12 <- Client.testList ps [1,2,3,4,5]
    ThriftTestUtils.clientLog $ show v12

    v13 <- Client.testSet ps (Set.fromList [1,2,3,4,5])
    ThriftTestUtils.clientLog $ show v13

    v14 <- Client.testStruct ps (Types.Xtruct (Just "hi") (Just 4) (Just 5) Nothing)
    ThriftTestUtils.clientLog $ show v14

    (testException ps "bad") `Control.Exception.catch` testExceptionHandler

    (testMultiException ps "ok") `Control.Exception.catch` testMultiExceptionHandler1
    (testMultiException ps "bad") `Control.Exception.catch` testMultiExceptionHandler2 `Control.Exception.catch` testMultiExceptionHandler3

    -- (  (Client.testMultiException ps "e" "e2">> ThriftTestUtils.clientLog "bad") `Control.Exception.catch` 

    tClose to
  where testException ps msg = do
            Client.testException ps "e"
            ThriftTestUtils.clientLog msg
            return ()

        testExceptionHandler (e :: Types.Xception) = do
            ThriftTestUtils.clientLog $ show e

        testMultiException ps msg = do
            _ <- Client.testMultiException ps "e" "e2"
            ThriftTestUtils.clientLog msg
            return ()

        testMultiExceptionHandler1 (e :: Types.Xception) = do
            ThriftTestUtils.clientLog $ show e

        testMultiExceptionHandler2 (e :: Types.Xception2) = do
            ThriftTestUtils.clientLog $ show e

        testMultiExceptionHandler3 (_ :: Control.Exception.SomeException) = do
            ThriftTestUtils.clientLog "ok"
client :: (String, Network.PortID) -> IO ()
client addr = do
    to <- hOpen addr
    let ps = (BinaryProtocol to, BinaryProtocol to)

    v1 <- Client.testString ps "bya"
    ThriftTestUtils.clientLog v1

    v2 <- Client.testByte ps 8
    ThriftTestUtils.clientLog $ show v2

    v3 <- Client.testByte ps (-8)
    ThriftTestUtils.clientLog $ show v3

    v4 <- Client.testI32 ps 32
    ThriftTestUtils.clientLog $ show v4

    v5 <- Client.testI32 ps (-32)
    ThriftTestUtils.clientLog $ show v5

    v6 <- Client.testI64 ps 64
    ThriftTestUtils.clientLog $ show v6

    v7 <- Client.testI64 ps (-64)
    ThriftTestUtils.clientLog $ show v7

    v8 <- Client.testDouble ps 3.14
    ThriftTestUtils.clientLog $ show v8

    v9 <- Client.testDouble ps (-3.14)
    ThriftTestUtils.clientLog $ show v9

    v10 <- Client.testMap ps (Map.fromList [(1,1),(2,2),(3,3)])
    ThriftTestUtils.clientLog $ show v10

    v11 <- Client.testStringMap ps (Map.fromList [("a","123"),("a b","with spaces "),("same","same"),("0","numeric key")])
    ThriftTestUtils.clientLog $ show v11

    v12 <- Client.testList ps [1,2,3,4,5]
    ThriftTestUtils.clientLog $ show v12

    v13 <- Client.testSet ps (Set.fromList [1,2,3,4,5])
    ThriftTestUtils.clientLog $ show v13

    v14 <- Client.testStruct ps (Types.Xtruct (Just "hi") (Just 4) (Just 5) Nothing)
    ThriftTestUtils.clientLog $ show v14

    (testException ps "bad") `Control.Exception.catch` testExceptionHandler

    (testMultiException ps "ok") `Control.Exception.catch` testMultiExceptionHandler1
    (testMultiException ps "bad") `Control.Exception.catch` testMultiExceptionHandler2 `Control.Exception.catch` testMultiExceptionHandler3

    -- (  (Client.testMultiException ps "e" "e2">> ThriftTestUtils.clientLog "bad") `Control.Exception.catch` 

    tClose to
  where testException ps msg = do
            Client.testException ps "e"
            ThriftTestUtils.clientLog msg
            return ()

        testExceptionHandler (e :: Types.Xception) = do
            ThriftTestUtils.clientLog $ show e

        testMultiException ps msg = do
            _ <- Client.testMultiException ps "e" "e2"
            ThriftTestUtils.clientLog msg
            return ()

        testMultiExceptionHandler1 (e :: Types.Xception) = do
            ThriftTestUtils.clientLog $ show e

        testMultiExceptionHandler2 (e :: Types.Xception2) = do
            ThriftTestUtils.clientLog $ show e

        testMultiExceptionHandler3 (_ :: Control.Exception.SomeException) = do
            ThriftTestUtils.clientLog "ok"
client addr = do
    to <- hOpen addr
    let ps = (BinaryProtocol to, BinaryProtocol to)

    v1 <- Client.testString ps "bya"
    ThriftTestUtils.clientLog v1

    v2 <- Client.testByte ps 8
    ThriftTestUtils.clientLog $ show v2

    v3 <- Client.testByte ps (-8)
    ThriftTestUtils.clientLog $ show v3

    v4 <- Client.testI32 ps 32
    ThriftTestUtils.clientLog $ show v4

    v5 <- Client.testI32 ps (-32)
    ThriftTestUtils.clientLog $ show v5

    v6 <- Client.testI64 ps 64
    ThriftTestUtils.clientLog $ show v6

    v7 <- Client.testI64 ps (-64)
    ThriftTestUtils.clientLog $ show v7

    v8 <- Client.testDouble ps 3.14
    ThriftTestUtils.clientLog $ show v8

    v9 <- Client.testDouble ps (-3.14)
    ThriftTestUtils.clientLog $ show v9

    v10 <- Client.testMap ps (Map.fromList [(1,1),(2,2),(3,3)])
    ThriftTestUtils.clientLog $ show v10

    v11 <- Client.testStringMap ps (Map.fromList [("a","123"),("a b","with spaces "),("same","same"),("0","numeric key")])
    ThriftTestUtils.clientLog $ show v11

    v12 <- Client.testList ps [1,2,3,4,5]
    ThriftTestUtils.clientLog $ show v12

    v13 <- Client.testSet ps (Set.fromList [1,2,3,4,5])
    ThriftTestUtils.clientLog $ show v13

    v14 <- Client.testStruct ps (Types.Xtruct (Just "hi") (Just 4) (Just 5) Nothing)
    ThriftTestUtils.clientLog $ show v14

    (testException ps "bad") `Control.Exception.catch` testExceptionHandler

    (testMultiException ps "ok") `Control.Exception.catch` testMultiExceptionHandler1
    (testMultiException ps "bad") `Control.Exception.catch` testMultiExceptionHandler2 `Control.Exception.catch` testMultiExceptionHandler3

    -- (  (Client.testMultiException ps "e" "e2">> ThriftTestUtils.clientLog "bad") `Control.Exception.catch` 

    tClose to
  where testException ps msg = do
            Client.testException ps "e"
            ThriftTestUtils.clientLog msg
            return ()

        testExceptionHandler (e :: Types.Xception) = do
            ThriftTestUtils.clientLog $ show e

        testMultiException ps msg = do
            _ <- Client.testMultiException ps "e" "e2"
            ThriftTestUtils.clientLog msg
            return ()

        testMultiExceptionHandler1 (e :: Types.Xception) = do
            ThriftTestUtils.clientLog $ show e

        testMultiExceptionHandler2 (e :: Types.Xception2) = do
            ThriftTestUtils.clientLog $ show e

        testMultiExceptionHandler3 (_ :: Control.Exception.SomeException) = do
            ThriftTestUtils.clientLog "ok"