diff --git a/Sound/OpenSoundControl/Time.hs b/Sound/OpenSoundControl/Time.hs
--- a/Sound/OpenSoundControl/Time.hs
+++ b/Sound/OpenSoundControl/Time.hs
@@ -1,5 +1,6 @@
 module Sound.OpenSoundControl.Time where
 
+import Control.Concurrent
 import Control.Monad
 import qualified Data.Time as T
 
@@ -32,3 +33,11 @@
 -- | Read current NTP timestamp.
 ntp :: IO NTP
 ntp = liftM utc_ntp utc
+
+-- | Pause current thread for the indicated duration, given in seconds.
+pause :: Double -> IO ()
+pause n = when (n > 1e-4) (threadDelay (floor (n * 1e6)))
+
+-- | Pause current thread until the given utc time.
+pauseUntil :: UTC -> IO ()
+pauseUntil t = pause . (t -) =<< utc
diff --git a/Sound/OpenSoundControl/Transport/UDP.hs b/Sound/OpenSoundControl/Transport/UDP.hs
--- a/Sound/OpenSoundControl/Transport/UDP.hs
+++ b/Sound/OpenSoundControl/Transport/UDP.hs
@@ -1,4 +1,7 @@
-module Sound.OpenSoundControl.Transport.UDP (UDP, openUDP) where
+module Sound.OpenSoundControl.Transport.UDP ( UDP
+                                            , openUDP
+                                            , udpServer
+                                            , sendTo, recvFrom ) where
 
 import Control.Monad
 import qualified Network.Socket as N
@@ -18,6 +21,26 @@
 openUDP :: String -> Int -> IO UDP
 openUDP host port = do fd <- N.socket N.AF_INET N.Datagram 0
                        a  <- N.inet_addr host
-                       N.connect fd (N.SockAddrInet (fromIntegral port) a)
+                       let sa = N.SockAddrInet (fromIntegral port) a
+                       N.connect fd sa
                        -- N.setSocketOption fd N.RecvTimeOut 1000
                        return (UDP fd)
+
+-- | Trivial udp server.
+udpServer :: String -> Int -> IO UDP
+udpServer host port = do fd <- N.socket N.AF_INET N.Datagram 0
+                         a  <- N.inet_addr host
+                         let sa = N.SockAddrInet (fromIntegral port) a
+                         N.bindSocket fd sa
+                         return (UDP fd)
+
+sendTo :: UDP -> OSC -> N.SockAddr -> IO ()
+sendTo (UDP fd) o a =
+    do N.sendTo fd (decode_str (encodeOSC o)) a
+       return ()
+
+recvFrom :: UDP -> IO (OSC, N.SockAddr)
+recvFrom (UDP fd) = 
+    do (s, _, a) <- N.recvFrom fd 8192
+       let o = (decodeOSC . encode_str) s
+       return (o, a)
diff --git a/hosc.cabal b/hosc.cabal
--- a/hosc.cabal
+++ b/hosc.cabal
@@ -1,5 +1,5 @@
 Name:              hosc
-Version:           0.3
+Version:           0.4
 Synopsis:          Haskell Open Sound Control
 Description:       hosc provides Sound.OpenSoundControl, a haskell
                    module implementing a subset of the Open Sound
@@ -14,7 +14,6 @@
 Tested-With:       GHC==6.8.2
 Build-Type:        Simple
 Cabal-Version:     >= 1.2
-
 Data-Files:        README
 
 Library
