Я хочу собрать основы для асинхронного 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 ()