1

我编写了一些基于 asio 的网络类,只要它们在单独的进程中运行,它们就可以按预期工作。在提高我的测试覆盖率的过程中,我遇到了接收器通常会停止接收数据的情况。由于我的 (CxxTest) 测试套件是单个应用程序,

我已经把代码放在这里了,在一个要点中,它很短,但它的“要点”是:

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

我的receive函数只是将新数据转储到一个向量中并存储它,它还会发出一个打印语句,其中包含它接收到的字节数。当我运行它时,我收到 1 个receive带有预期数据量的调用,有时我会收到 2 个,很少会收到 3 个。

现在,当我把这个文件分成两半时,一个只做发送端,另一个只做接收端,效果很好。除了删除每个部分的不相关贡献之外,绝对没有任何变化。

我在 WireShark 中观看过,所有传输都按预期进行,因为它们应该是同步的,这对我来说很有意义。就好像接收处理程序没有看到任何新的进来,所以它只是静静地坐着。我怎么会丢失数据?我是 asio 的新手,所以我希望我只是在做一些明显愚蠢的事情!

4

1 回答 1

1

好的第二次尝试 :D 但这次我检查了它。

您的问题是您使用相同的端点进行发送和接收。我也发现了这个

一般来说,并发使用不同的对象是安全的,但并发使用单个对象是不安全的。但是,诸如 io_service 之类的类型提供了更强的保证,即并发使用单个对象是安全的。

因此,为您创建一个端点,txsockrxsock-> 发送到 send_end/ 从 rec_end 接收创建一个端点,我得到了这个结果。

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);
  • 在测试时我发现如果我用它替换async_receive_fromasync_receive也可以(在我的机器上)而不添加端点。
  • 如果我替换 txsock 并将其连接到端点,它也可以send_to工作send
于 2013-08-27T20:42:45.340 回答