#include <iostream>
#include <time.h>
#include <chrono>
#include <ctime>
#include <string>
#include <boost/asio.hpp>
#include "boost/bind.hpp"
#include <string>
#include <bits/stdc++.h>
#include <thread>
#include <boost/thread.hpp>
using namespace std;
using boost::asio::io_service;
const short multicast_port = 30001;
class receiver
{
public:
receiver(boost::asio::io_service& io_service,
const boost::asio::ip::address& listen_address,
const boost::asio::ip::address& multicast_address)
: socket_(io_service)
{
// Create the socket so that multiple may be bound to the same address.
boost::asio::ip::udp::endpoint listen_endpoint(
listen_address, multicast_port);
socket_.open(listen_endpoint.protocol());
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
socket_.bind(listen_endpoint);
// Join the multicast group.
socket_.set_option(
boost::asio::ip::multicast::join_group(multicast_address));
socket_.async_receive_from(
boost::asio::buffer(data_, max_length), sender_endpoint_,
boost::bind(&receiver::handle_receive_from, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_receive_from(const boost::system::error_code& error,
size_t bytes_recvd)
{
if (!error)
{
std::cout.write(data_, bytes_recvd);
std::chrono::time_point< std::chrono::system_clock > now = std::chrono::system_clock::now();
auto duration = now.time_since_epoch();
auto nanoseconds = std::chrono::duration_cast< std::chrono::nanoseconds >( duration );
std::cout<<" "<<boost::this_thread::get_id()<<" "<<nanoseconds.count() << " nanoseconds "<<std::endl;
socket_.async_receive_from(
boost::asio::buffer(data_, max_length), sender_endpoint_,
boost::bind(&receiver::handle_receive_from, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
private:
boost::asio::ip::udp::socket socket_;
boost::asio::ip::udp::endpoint sender_endpoint_;
enum { max_length = 1024 };
char data_[max_length];
};
int main(int argc, char* argv[])
{
try
{
if (argc != 3)
{
std::cerr << "Usage: receiver <listen_address> <multicast_address>n";
std::cerr << " For IPv4, try:n";
std::cerr << " receiver 0.0.0.0 239.255.0.1n";
std::cerr << " For IPv6, try:n";
std::cerr << " receiver 0::0 ff31::8000:1234n";
return 1;
}
boost::asio::io_service io_service,io_service1;
receiver r(io_service,
boost::asio::ip::address::from_string(argv[1]),
boost::asio::ip::address::from_string(argv[2]));
receiver r1(io_service1,
boost::asio::ip::address::from_string(argv[1]),
boost::asio::ip::address::from_string(argv[2]));
boost::thread thread1{[&io_service](){ io_service.run(); }};
boost::thread thread2{[&io_service1](){ io_service1.run(); }};
thread1.join();
thread2.join();
// boost::asio::io_service io_service;
// receiver r(io_service,
// boost::asio::ip::address::from_string(argv[1]),
// boost::asio::ip::address::from_string(argv[2]));
// for (int i = 0; i < 2; ++i) {
// boost::thread z(boost::bind(&boost::asio::io_service::run, &io_service));
// z.join();
// }
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "n";
}
return 0;
}
我已经更新了整个程序。 此代码工作正常,但无法将线程代码放入循环中。 我能够手动创建多个接收器(线程(,但无法使用循环创建多个线程。
我已经更新了整个程序。 此代码工作正常,但无法将线程代码放入循环中。 我能够手动创建多个接收器(线程(,但无法使用循环创建多个线程。
你没有展示receiver
类,我想它看起来像
struct receiver
{
receiver(boost::asio::io_service& io, ...)
: io(io), ...
{
}
boost::asio::io_service& io;
};
这里的关键点是receiver
存储对io_service
对象的引用。io_service
是 asio 中许多无法复制/移动的类之一。如果类包含引用,则编译器无法为该类生成复制/移动操作。此外,receiver
没有默认构造函数。例如,这些限制结果不能用于存储接收器vector<receiver>
- 在循环中创建对象时会很有用。
解决此问题的简单方法是使用(智能(指针 -shared_ptr
。
如果io_service
未在receiver
实例之间共享,则可以将其作为receiver
的成员变量:
struct receiver {
receiver(boost::asio::ip::address, boost::asio::ip::address)
: th(boost::bind(&boost::asio::io_service::run,&ioService))
{ // ^^^ thread is started here
}
~receiver() {
if (th.joinable())
th.join();
}
boost::asio::io_service ioService;
boost::thread th;
};
main
可以减少到:
try {
if (argc != 3) {
std::cerr << "Usage: receiver <listen_address> <multicast_address>n";
std::cerr << " For IPv4, try:n";
std::cerr << " receiver 0.0.0.0 239.255.0.1n";
std::cerr << " For IPv6, try:n";
std::cerr << " receiver 0::0 ff31::8000:1234n";
return 1;
}
std::vector<boost::shared_ptr<receiver>> receivers;
for (int i = 0; i < 2; ++i)
{
receivers.push_back(boost::make_shared<receiver>(boost::asio::ip::address::from_string(argv[1]),
boost::asio::ip::address::from_string(argv[2])));
}
}
catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << "n";
}
编译