{-# LANGUAGE OverloadedStrings #-} module Main where import Network.Socket hiding (send, sendTo, recv, recvFrom) import Network.Socket.ByteString import Control.Concurrent import Control.Exception import Control.Monad (forever) import System.IO ( IOMode (ReadWriteMode) ) import qualified Data.ByteString as BS main = do sock <- socket AF_INET6 Datagram defaultProtocol -- lookup destination to get a SockAddr let hints = defaultHints { addrFamily = AF_INET6, addrSocketType = Datagram} serverAddr <- addrAddress . head <$> getAddrInfo (Just hints) (Just "::1") (Just "7331") print serverAddr bind sock serverAddr print sock forever $ do receivedStuff <- recvFrom sock 65535 -- blocks forkIO $ bracket newSendSocket close (serveReceive receivedStuff) serveReceive :: (BS.ByteString, SockAddr) -> Socket -> IO () serveReceive (msg, fromAddr) sendSocket = do print sendSocket putStrLn $ "Got message " ++ show msg ++ " from " ++ show fromAddr -- important: as new socket sends from a different port, the receiving client must use an unconnected socket! sentBytes <- sendTo sendSocket ("Hi, thx for " `BS.append` msg) fromAddr putStrLn $ "sent response of " ++ show sentBytes ++ "bytes" return () newSendSocket :: IO Socket newSendSocket = socket AF_INET6 Datagram defaultProtocol