Асинхронный UDP сервер / клиент как база для IPC в Haskell - PullRequest
2 голосов
/ 28 ноября 2011

Я хочу собрать основы для асинхронного UDP IPC в Haskell. Для этого отправитель / получатель должен выдать, например, синхронный прием (или отправка, в зависимости от того, с какой стороны вы его просматриваете), поток и выполнение других задач.

Это может включать определение нового типа данных, который состоит из необязательных серийных номеров сообщений / данных и некоторого типа буфера, чтобы поток отправки мог прекратить отправку, когда он получает уведомление от получателя о том, что он не может справиться со скоростью.

Я стремлюсь сделать это максимально легким и асинхронным, насколько это возможно.

Я пробовал несколько вещей, таких как запуск нового потока приема для каждого пакета (этот подход использовался в статье о многопользовательских онлайн-играх), но это почти остановило все.

Ниже мой невинный первый взгляд на это. Любая помощь, например, создание буферов, создание серийных номеров или реализация DCCP (которую я не смог найти) в Haskell приветствуется. - Я бы не хотел вдаваться в дискуссии о UDP против TCP и т. Д.

Мой фрагмент перестает работать, когда что-то не синхронизируется, например, когда данные не поступают больше или когда поступает меньше данных, чем ожидалось. Я ищу, как сказано, для некоторого способа облегченной (полулегкой: D) синхронизации между отправляющим и получающим потоком для примера такого.

main = withSocketsDo $ do
        s <- socket AF_INET Datagram defaultProtocol
        hostAddr <- inet_addr host
        done <- newEmptyMVar
        let p = B.pack "ping"
        thread <- forkIO $ receiveMessages s done
        forM_ [0 .. 10000] $ \i -> do
              sendAllTo s (B.pack  "ping") (SockAddrInet port hostAddr)
        takeMVar done
        killThread thread
        sClose s
        return()

receiveMessages :: Socket ->  MVar () -> IO ()
receiveMessages socket done = do
        forM_ [0 .. 10000] $ \i -> do
              r <- recvFrom socket 1024
              print (r) --this is a placeholder to make the fun complete
        putMVar done ()
...