异步 UDP 服务器/客户端作为 Haskell 中 IPC 的基础

发布于 2024-12-18 03:53:22 字数 1202 浏览 5 评论 0原文

我想将 Haskell 中异步 UDP IPC 的基础知识放在一起。为此,发送方/接收方应发出同步接收(或发送,取决于您从哪一侧查看)线程并继续执行其他任务。

这可能涉及定义一种新的数据类型,该类型由可选的消息/数据序列号和某种缓冲区组成,以便发送线程在从接收器收到无法处理速度的通知时可以停止发送。

我的目标是使其重量轻且耐用。尽可能异步。

我尝试过很多事情,例如为每个数据包启动一个新的接收线程(这种方法来自一篇关于多人在线游戏的论文),但这几乎让所有事情都陷入了停顿。

以下是我对此的第一次无辜的看法。任何有关例如在 Haskell 中创建缓冲区、创建序列号或 DCCP 实现(我找不到)的帮助都表示赞赏。 - 我不想陷入有关 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 ()

I want to put together the basics for asynchronous UDP IPC in Haskell. For this the sender/receiver should issue e.g. an synchronous receive (or send, depending from what side you view it) thread and carry on with other tasks.

This might involve to define a new data type that consists of optional message/data serial numbers and some sort of buffer so that the send thread can stop sending when it gets a notification from the receiver that it cannot cope with the speed.

I aim to make this as light weight & asynchronous as possible.

I have tried a number of things such as starting a new receive thread for every packet (took this approach from a paper about multi player online games), but this was grinding almost everything to a halt.

Below is my innocent first take on this. Any help on e.g. creating buffers, creating serial numbers or a DCCP implementation (that I could not find) in Haskell appreciated. - I would not like to get into opinionated discussions about UDP vs TCP etc..

My snippet stops working once something gets out of sync e.g. when no data arrives any more or when less data arrives than expected. I am looking as said for some way of lightweight (featherweight :D) sync between the send and the receive thread of for an example of such.

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 ()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文