c++基于asio的组播:windows linux通信

Posted qianbo_insist

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++基于asio的组播:windows linux通信相关的知识,希望对你有一定的参考价值。

上代码,非常简单,使用参数控制发送和接收

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>

// 3rd party includes.
#include <asio.hpp>
#include <string>
#include <thread>
using namespace std;
using namespace asio::ip;
void read(asio::ip::udp::socket& socket)
{
	asio::ip::udp::endpoint sender;
	std::vector<char> buffer;
	std::size_t bytes_readable = 0;
	for (;;)
	{
		// Poll until data is available.
		while (!bytes_readable)
		{
			// Issue command to socket to get number of bytes readable.
			asio::socket_base::bytes_readable num_of_bytes_readable(true);
			socket.io_control(num_of_bytes_readable);

			// Get the value from the command.
			bytes_readable = num_of_bytes_readable.get();

			// If there is no data available, then sleep.
			if (!bytes_readable)
			{
				std::this_thread::sleep_for(std::chrono::milliseconds(200));
				//boost::this_thread::sleep(boost::posix_time::seconds(1));
			}
		}

		// Resize the buffer to store all available data.
		buffer.resize(bytes_readable);

		// Read available data.
		socket.receive_from(
			asio::buffer(buffer, bytes_readable),
			sender);

		// Extract data from the buffer.
		std::string message(buffer.begin(), buffer.end());

		// Output data.
		std::cout << "Received message:\\n";
		std::cout << message << std::endl;
	}
}

void write(asio::ip::udp::socket& socket,
	asio::ip::udp::endpoint& destination)
{
	//std::string message;

	//char buffer[256];
	//sprintf(buffer, msearchmsgfmt, "upnp:rootdevice");
	/*socket.async_send_to(
		boost::asio::buffer(buffer, strlen(buffer)), endpoint_,
		boost::bind(handle_send_to, this,
			boost::asio::placeholders::error));*/

	for (unsigned int i = 0; i < 300; ++i)
	{
		//std::ostringstream stream;
		//stream << i;
		//message = stream.str();
		char buffer[256];
		sprintf(buffer, "this is test %d", i);
		std::cout << "Sent message ok->" << ""<< std::endl;
		socket.send_to(asio::buffer(buffer, strlen(buffer)), destination);
		std::this_thread::sleep_for(std::chrono::milliseconds(5000));
	}
}




int main(int argc, char* argv[])
{
    // Extract command-line arguments.
	bool receiver = true;
	string addr = "234.0.0.1";
	if (argc < 2)
	{
		receiver = true;
	}
	else
		receiver = std::string(argv[1]) == "s" ? false : true;

	asio::ip::address address =
        asio::ip::address::from_string(addr);
    unsigned short port = 1900;  //boost::lexical_cast<unsigned short>(1900);
	asio::ip::address local =
		asio::ip::address::from_string("0.0.0.0");
	//unsigned short localport = 50000;
    // Create socket.
    asio::io_context service;
    udp::socket socket(service);

	
    socket.open(asio::ip::udp::v4());

    socket.set_option(udp::socket::reuse_address(true));

   
    //socket.set_option(asio::ip::multicast::enable_loopback(true));
    socket.bind(
        udp::endpoint(asio::ip::address_v4::any(),
            receiver ? port : 16200));

	//socket.bind(
	//	udp::endpoint(local,1900));


    udp::endpoint destination(address, port);

    // Join group.
    socket.set_option(asio::ip::multicast::join_group(address));

    // Start read or write loops based on command line options.
	//std::thread t([](){
	//	printf("this is a test");
	//}); // pass by reference
	
	if (receiver)
		read(socket);
	else
		write(socket,destination);
	//std::thread t(read, std::ref(socket)); // pass by reference
    //write(socket, destination);
    return 0;
}

编译

g++ -std=c++11 main.cpp -o out -lpthread -I./include
由于使用了c++11 线程所以使用c++11 编译,线程必须加上 -lpthread 参数, 使用asio,
所以includ 是asio的include头文件
linux 下执行
./out
没有参数则表示接收,开始执行接收

windows下编译使用vs,加上一个参数
加入s参数
-s 参数表示发送
windows下CTRL+F5执行

执行结果

windows 和 linux 组播通信
window程序开始发送
linux程序开始接收

以上是关于c++基于asio的组播:windows linux通信的主要内容,如果未能解决你的问题,请参考以下文章

asio 组播包ssdp

win7如何设允许udp组播

组播之IGMP(2)

浅谈Android中的组播(多播)

组播基本知识概述

IPV6 组播学习理解