Asio 异步 UDP 通信的 API 好奇怪啊

2020-03-01 22:38:27 +08:00
 mrcn

在 Boost 中 UDP 异步接收数据的 API 是这样的:async_receive_from(buffer, endpoint[, flags], handler),也就是下面的用法:

udp_socket->async_receive_from(
            asio::buffer(recv_buffer), sender_endpoint,
            std::bind(&handle_udp_recv, this,
                      std::placeholders::_1,
                      std::placeholders::_2));

handle_udp_recv是接收到数据的回调,回调得到的参数只有 error 和 bytes_transferred 两个,第一个是错误号,第二个是拿到数据的长度,而得到的数据却是存放在调用async_receive_from时提供的 buffer 中的。

我想象的 API 设计应该是将 buffer 和 sender_endpoint 同样作为参数传给回调,这样似乎也更容易减少耦合。不过设计成这样肯定是有原因的,是为什么呢?

3069 次点击
所在节点    C++
7 条回复
future0906
2020-03-01 23:13:38 +08:00
你不想管的就叫耦合?
catror
2020-03-01 23:49:33 +08:00
你自己创建的东西,当然要自己维护才叫不耦合,正确做法是放到成员变量里。
ASIO 的基本想法是,IO 操作的回调仅仅作为 IO 完成的通知,其他的不管。
iriyave
2020-03-02 05:32:53 +08:00
在回调中收到数据处理完后,一般会对 buffer 做一些处理,如果是单独申请的内存,要释放掉,如果是重复使用的内存就要传递给下一次异步调用,而且这个 buffer 有可能是直接分配的内存,或是 vector, array, string 之类的,有时还要考虑线程安全之类的问题,你觉得这些处理直接通过回调函数传给你的 buffer 指针参数处理好吗?
codehz
2020-03-02 08:40:36 +08:00
回调不是可以一键 lambda 捕获的么,所以为啥还要再在 api 里复制过去呢
codehz
2020-03-02 08:43:41 +08:00
即使不考虑 lambda,你这里也用了 boost::bind,这意味着你可以把 buffer 通过 bind 给传递过去
或者按你说的,用类的属性( this 上)
你看这不是很多途径么,然后同时也保持了 api 的泛用性
mrcn
2020-03-02 09:49:57 +08:00
@future0906
@catror
@iriyave
@codehz
明白了,感谢!
hardwork
2020-03-02 10:26:25 +08:00
asio 这里不管 buffer,要你自己提供也就是自己管理,所以回调函数没有 buffer,因为你自己知道 buffer 在哪里。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/648957

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX