异步 UDP 服务器/客户端作为 Haskell 中 IPC 的基础
我想将 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果你不信任你的信使,你就永远无法在任何事情上达成一致——甚至连一点点“都不是”我们还没完成”!
If you don't trust your messenger, you can never agree on anything -- not even a single bit like "are we done yet"!