質問が以前に回答されている場合は事前にお詫び申し上げますが、検索しても役に立たないものは見つかりませんでした。質問のタイトルが示すように、サーバーからメッセージをリッスンしている一連のクライアントにパッケージをブロードキャストしようとしています。
クライアントは、1 秒間に受信したメッセージの数をカウントします。
サーバー側は次のようになります。
class Server
{
public:
Server(boost::asio::io_service& io)
: socket(io, udp::endpoint(udp::v4(), 8888))
, broadcastEndpoint(address_v4::broadcast(), 8888)
, tickHandler(boost::bind(&Server::Tick, this, boost::asio::placeholders::error))
, timer(io, boost::posix_time::milliseconds(20))
{
socket.set_option(boost::asio::socket_base::reuse_address(true));
socket.set_option(boost::asio::socket_base::broadcast(true));
timer.async_wait(tickHandler);
}
private:
void Tick(const boost::system::error_code&)
{
socket.send_to(boost::asio::buffer(buffer), broadcastEndpoint);
timer.expires_at(timer.expires_at() + boost::posix_time::milliseconds(20));
timer.async_wait(tickHandler);
}
private:
udp::socket socket;
udp::endpoint broadcastEndpoint;
boost::function<void(const boost::system::error_code&)> tickHandler;
boost::asio::deadline_timer timer;
boost::array<char, 100> buffer;
};
次の方法で初期化および実行されます。
int main()
{
try
{
boost::asio::io_service io;
Server server(io);
io.run();
}
catch (const std::exception& e)
{
std::cerr << e.what() << "\n";
}
return 0;
}
これは(どうやら)うまくいきます。さぁ、お客様が来て…
void HandleReceive(const boost::system::error_code&, std::size_t bytes)
{
std::cout << "Got " << bytes << " bytes\n";
}
int main(int argc, char* argv[])
{
if (argc != 2)
{
std::cerr << "Usage: " << argv[0] << " <host>\n";
return 1;
}
try
{
boost::asio::io_service io;
udp::resolver resolver(io);
udp::resolver::query query(udp::v4(), argv[1], "1666");
udp::endpoint serverEndpoint = *resolver.resolve(query);
//std::cout << serverEndpoint.address() << "\n";
udp::socket socket(io);
socket.open(udp::v4());
socket.bind(serverEndpoint);
udp::endpoint senderEndpoint;
boost::array<char, 300> buffer;
auto counter = 0;
auto start = std::chrono::system_clock::now();
while (true)
{
socket.receive_from(boost::asio::buffer(buffer), senderEndpoint);
++counter;
auto current = std::chrono::system_clock::now();
if (current - start >= std::chrono::seconds(1))
{
std::cout << counter << "\n";
counter = 0;
start = current;
}
}
}
catch (const std::exception& e)
{
std::cerr << e.what() << "\n";
}
これは、サーバーとクライアントの両方を同じマシンで実行している場合は機能しますが、クライアントを実行しているマシンとは異なるマシンでサーバーを実行している場合は機能しません。
まず、サーバーのアドレスを解決しなければならないのは奇妙に思えます。おそらく、ブロードキャストが実際にどのように機能するかはわかりませんが、サーバーはブロードキャストオプションをオンにしたソケットを使用してメッセージを送信し、同じネットワーク内のすべてのソケットに到達すると思いました。
address_v4::any()
クライアントのソケットをアドレスにバインドする必要があることを読みました。私はしました、それは動作しません(すでにアドレス/ポートを使用しているソケットについて何か言います)。
前もって感謝します。
PS: 私は Windows 8 を使用しています。