我已经编写了一些基于asio的网络类,只要它们在不同的进程中运行,它们就可以按预期工作。在提高测试覆盖率的过程中,我遇到了接收器通常会停止接收数据的情况。由于我的(CxxTest)测试套件是单个应用程序,
我已将代码抛出here, in a gist,它很短,但它的“要点”是:
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
函数只是将新数据转储到一个向量中并存储它,它还会显示一个带有多少字节的print语句。当我运行此操作时,我会收到1 receive
次调用预期数量的数据,有时我得到2,非常我很少得到3。
现在,当我把这个文件分成两半时,一个只做发送端,另一个只做接收端,它工作得很好。除了删除每个部分的无关贡献外,绝对没有任何变化。
我在WireShark中观看过,并且所有传输都按预期发生,因为它们应该是同步的,这对我来说很有意义。就好像接收处理程序没有看到任何新的内容,所以它只是静静地坐着。我怎么错过这些数据?我是asio的新手,所以我希望我只是做一些明显愚蠢的事情!
答案 0 :(得分:1)
确定第二次尝试:D但是这次我检查了它。
您的问题是您使用相同的端点进行发送和接收。我还找到了this:
通常,并行使用不同的对象是安全的,但同时使用单个对象是不安全的。但是,诸如io_service之类的类型提供了更强的保证,即同时使用单个对象是安全的。
因此,为txsock
创建一个端点,为rxsock
创建一个端点 - >从rec_end发送到send_end / receive我得到了这个结果。
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_from
替换为async_receive
,它也可以(在我的机器上)无需添加端点。send_to
替换为send
并将txsock连接到端点,它也可以。