简体   繁体   中英

boost::asio UDP send/receive in the same process

I've written some asio-based networking classes, and they work as expected as long as they are run in separate processes. In the process of improving my test coverage, I've run into a case where the receiver will usually stop receiving data. Since my (CxxTest) test suite is a single application,

I've thrown the code up here, in a gist , it's pretty short, but the "gist" of it is:

create endpoint (127.0.0.1:54321, shared by rx/tx)
create service
create tx socket
  open
  set reusable(true)
  set broadcast(true)
create rx socket
  open
  bind to endpoint
  async_receive...
create thread(io_service::run)

send data several times
wait a few seconds

io_service::stop
thread::join

My receive function just dumps the new data into a vector and stores it, it also barks out a print statement with how many bytes it received. When I run this, I get 1 receive call with an expected amount of data, sometimes I get 2, and very rarely I've gotten 3.

Now, when I rip this file in half, one only doing the transmit side, the other only doing the receive side, it works great. Absolutely no changes other than removing each part's irrelevant contributions.

I have watched in WireShark, and all of the transmits are happening as expected, and since they're supposed to be synchronous, that makes sense to me. It's as if the receive handler isn't seeing anything new come in, so it just sits quietly. How am I missing the data? I'm new to asio, so I hope I'm just doing something obviously dumb!

OK second try :D but this time I checked it.

Your problem is that you are using the same endpoint for send and receive. Also I found this :

In general, it is safe to make concurrent use of distinct objects, but unsafe to make concurrent use of a single object. However, types such as io_service provide a stronger guarantee that it is safe to use a single object concurrently.

So create one endpoint for your txsock and one for rxsock -> sending to send_end/ receiving from rec_end I got this result.

send(2006)
receive(2006)
receive(2006)
send(2006)
receive(2006)
send(2006)
receive(2006)
send(2006)
send(2006)
receive(2006)
receive(2006)
send(2006)
send(2006)
receive(2006)
receive(2006)
send(2006)
received 8 packet(s) total
receive(0)
receive error: The I/O operation has been aborted because of either a thread exit or an application request
...
ba::ip::udp::endpoint send_end;
ba::ip::udp::endpoint rec_end;

send_end = ba::ip::udp::endpoint(address, 54321);
rec_end = ba::ip::udp::endpoint(address, 54321);

// ...

rxsock->bind(rec_end);
// in go and receive
rxsock->async_receive_from(ba::buffer(buffer, BUF_SZ), rec_end,
    boost::bind(receive, ba::placeholders::error, ba::placeholders::bytes_transferred));

// ...
std::size_t sz = socket.send_to(b.data(), send_end);
  • While testing I found out that if I replace the async_receive_from by async_receive it also works (on my machine) without adding an endpoint.
  • It also works if I replace send_to by send and connect the txsock to the endpoint.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM