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