asio 组播包ssdp

Posted qianbo_insist

tags:

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

asio 组播ssdp

注意:低版本的asio lib必须要加入预定义 ASIO_STANDALONE

上次写了一个boost加入组播的代码,这次我们不在使用boost,直接使用asio

1、加入组播是基础,
2、然后再搜索ssdp信息,
3、然后再回单播信息。

以上就是流程,不要小看这几句话,按照这个流程走,ssdp信息才可以搜索并正确回复。

搜索信息

//
以下是搜索信息,只要搜索到我们定义的,我们就可以回复信息,否则不予理睬

static const char *g_Searchssdp = "M-SEARCH * HTTP/1.1\\r\\nHOST:239.255.255.250:1900\\r\\nMAN:\\"ssdp:discover\\"\\r\\nST:urn:schemas-upnp-org:device:MediaRenderer:1\\r\\nMX:3\\r\\n\\r\\n";

以下函数为比较,虽然粗糙,实际上是原理

void handle_receive(char *data,size_t length)
	{
		string d(data,length);
		if(d.compare(g_Searchssdp)==0)
		{
		// do what you want!
		}
		// fix me
	}

show me the code

#include <iostream>
#include <string>
#include <asio.hpp>
//#include "boost/bind.hpp"
//ssdp 协议

const short multicast_port = 1900;
using namespace std;
using namespace asio;
using namespace asio::ip;
class receiver
{
public:
	receiver(asio::io_context& io_service,
		const asio::ip::address& listen_address,
		const asio::ip::address& multicast_address)
		: socket_(io_service)
	{
		// Create the socket so that multiple may be bound to the same address.
		asio::ip::udp::endpoint listen_endpoint(
			listen_address, multicast_port);
		socket_.open(listen_endpoint.protocol());
		socket_.set_option(asio::ip::udp::socket::reuse_address(true));
		socket_.bind(listen_endpoint);

		// Join the multicast group.
		socket_.set_option(
			asio::ip::multicast::join_group(multicast_address));

	}
	void handle_receive(char *data,size_t length)
	{
		string d(data,length);
		if(d.compare(g_Searchssdp)==0)
		{
		// do what you want!
		}
		// fix me
	}
	void start_receive()
	{
		socket_.async_receive_from(
			asio::buffer(data_, max_length), sender_endpoint_,
			[this](std::error_code &ec, std::size_t bytes_recvd)
		{
			if (!ec)
			{
				std::cout.write(data_, bytes_recvd);
				std::cout << std::endl;
				handle_receive(data_, bytes_recvd);
				start_receive();
				//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:
	asio::ip::udp::socket socket_;
	asio::ip::udp::endpoint sender_endpoint_;
	enum { max_length = 1024 };
	char data_[max_length];
};

int main(int argc, char* argv[])
{
	try
	{
		asio::io_context io_service;
		receiver r(io_service,
			asio::ip::address::from_string("192.168.1.144"),
			asio::ip::address::from_string("239.255.255.250"));
		io_service.run();
	}
	catch (std::exception& e)
	{
		std::cerr << "Exception: " << e.what() << "\\n";
	}

	return 0;
}

下面一节会继续介绍如何回复信息,请关注我

以上是关于asio 组播包ssdp的主要内容,如果未能解决你的问题,请参考以下文章

ssdp安全-攻击和防御

关于socket组播和ssdp

关于socket组播和ssdp[修改1.2]

开发日常网卡驱动中如何设置组播mac地址?

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

java与网络(IPv4组播)