关于socket组播和ssdp(二)
关于socket组播和ssdp(一)
1、说明
在制作的过程中,实际上ssdp发现协议特别简单,只是加入组播后,发送搜索的字符串,然后再在单播上接收,如果是发送,则要发送到多播地址,而且,发送的字符串不能出错,这里说明作者的一个错误,开始时,“MAN: “ssdp:discover”\r\n”,一直写成了"MAN: ssdp:discover\r\n",所以在单播上没有收到数据,值得注意!
2、show me the code,以下用boost库来做组播的接收和发送
socket.bind(
udp::endpoint(boost::asio::ip::address_v4::any(),
receiver ? port /* same as multicast port /
: 6200 / any */));
以上这句话比较重要,在使用发送的时候,使用组播端口,接收的时候,使用本地的一个端口,切记!
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
// 3rd party includes.
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <string>static const char msearchmsgfmt[] = "M-SEARCH * HTTP/1.1\r\n"
"Connection: close"
"HOST: 239.255.255.250:1900\r\n"
"ST: %s\r\n"
"MAN: \"ssdp:discover\"\r\n"
"USER-AGENT: qbupnp 1.0"
"MX: 3\r\n\r\n";void read(boost::asio::ip::udp::socket& socket){boost::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.boost::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){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(boost::asio::buffer(buffer, bytes_readable),sender);// Extract data from the buffer.std::string message(buffer.begin(), buffer.end());// Output data.std::cout << "Received message: ";std::cout << message << std::endl;}}void write(boost::asio::ip::udp::socket& socket,boost::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 < 3; ++i){//std::ostringstream stream;//stream << i;//message = stream.str();socket.send_to(boost::asio::buffer(msearchmsgfmt, strlen(msearchmsgfmt)), destination);std::cout << "Sent message: " << message << std::endl;}
}int main(int argc, char* argv[])
{// Extract command-line arguments.bool receiver = false;// std::string(argv[1]) == "receive";boost::asio::ip::address address =boost::asio::ip::address::from_string("239.255.255.250");unsigned short port = 1900; // Create socket.using boost::asio::ip::udp;boost::asio::io_service service;udp::socket socket(service);socket.open(boost::asio::ip::udp::v4());// Allow other processes to reuse the address, permitting other processes on// the same machine to use the multicast address.socket.set_option(udp::socket::reuse_address(true));socket.set_option(boost::asio::ip::multicast::enable_loopback(true));socket.bind(udp::endpoint(boost::asio::ip::address_v4::any(),receiver ? port /* same as multicast port */: 6200 /* any */));udp::endpoint destination(address, port);// Join group.namespace ip = boost::asio::ip;socket.set_option(ip::multicast::join_group(address));// Start read or write loops based on command line options.if (receiver) read(socket);elsewrite(socket, destination);return 0;
}
3、有关于wireshark 抓包
注意使用port 1900 的包在局域网里面应该是有很多的,包含网关的,chrome 发送的ssdp,等等,读者可以适当自己过滤加上not host 192.168.0.1 诸如此类的网关过滤
4 、 接下来使用http去接收和发送数据
建议
1 使用boost asio库直接接收发送,甚至直接使用asio
2 使用httplib接收发送
3 使用nlohmann 解析json
4 xml 库可以使用ixml,或者直接手动解析:
如何手动解析xml
以上为什么推荐使用httplib,和 nlohmann,这两个只要加入头文件即可,不用编译。为什么使用asio,可以直接使用头文件,简化加载库,以及asio封装得非常方便。
5、总结
使用以上工具和方法,作者做出了一个ssdp搜索和控制工具,仿照libpnp来做的,研读了很多代码,读者可以沿着作者走过的路走一遍。
打印控制点
投屏服务客户端
总之,dlna和libupnp协议并不难懂,其实就是一系列协议的组合,甚至大量使用了http协议,在文件点播和直播方面,可以使用rtsp协议和http协议等等,只要深度研究这些基础协议,就可以做出相应的产品。
以上都是作者的事件经验,读者需要交流,可以使用418511899@qq.com,或者微信联系。
关于socket组播和ssdp(二)相关推荐
- 关于socket组播和ssdp(一)[修改1.2]
有关于ssdp安全的文章 ssdp攻击和防御 组播 单播和广播 组播方式解决了单播情况下数据的重复拷贝及带宽的重复占用,也解决了广播方式下带宽资源的浪费,我们知道单播在发送者和每一接收者之间实现点对点 ...
- asio 组播包ssdp
asio 组播ssdp 注意:低版本的asio lib必须要加入预定义 ASIO_STANDALONE 上次写了一个boost加入组播的代码,这次我们不在使用boost,直接使用asio 1.加入组播 ...
- 三种组播×××承载方案对比
方案一:基于PIM-SM/mGRE的承载方案 如图所示,公网运行PIM-SM协议,且PE 1.PE2和PE 3都支持mVRF实例. 不同的mVRF站点加入到同一个组播域(MD)中,通过MD内自动建立的 ...
- IP组播基础(一)点到多点应用特点、组播基本架构、组播IP、MAC地址结构组成
文章目录 前言 点到多点应用的发展与部署 传统点到点应用 点到多点应用 用单播方式部署点到多点应用 用广播的方式部署点到多点网络 组播方式部署点到多点应用 组播基本概述 组播基本架构 组播源到路由器 ...
- IP组播技术在视频中的应用(1)
IP组播技术在视频中的应用(1) IP组播技术在视频中的应用 摘要:随着流媒体.视频等业务在 Internet 上的相继开展, IP 组播技术和应用开始快速发展.本文主要分析 IP 组播技术的产生.概 ...
- UDP协议、广播、组播和多路复用(网络编程二)
一.udp通信 1. 基本流程 udp发送端 udp接收端 socket() socket() bind(); bind(); sendto/recvfrom sendto/recvfrom clos ...
- JAVA 网络编程(5) SOCKET UDP 单播和组播,以及组播其他机器收不到报文的解决方法
UDP既可以单播也可以组播 一,单播 单播的过程为 发送方: InetAddress destAddr = InetAddress.getByName("192.168.4.199" ...
- 网络编程-Socket套接字(TCP、UDP、广播和组播通信)
socket套接字 socket是一个编程接口(网络编程接口) 作用是用来实现网络上不同的主机的应用进程之间进行双向通信 套接字是一种特殊的文件描述符 也就意味着我们使用套接字实现网络通信的时候可以用 ...
- Socket网络编程之组播实现(C++,Rust)
实际项目中,经常需要使用组播,代码示例如下: 一.C++实现(Windows) 服务端源码 服务端需要添加加入组播组的相关代码. #include "stdafx.h" #incl ...
最新文章
- 读书:个人成长 -- 即兴演讲
- 为数字资产交易设计安全的钱包架构
- wifi boombox android,android filament入门,GLB和GLTF模型查看器
- 【2020蓝桥杯】Python组真题解析 - 第十一届蓝桥杯
- Bookshelf 2
- js 字符串插入_前端利器React,为什么推荐JSX来替换JS
- 调用微信支付接口总结
- Android so减包相关
- 一份来自滴滴运维工程师的监控系统建设心得
- md5加解密工具 java_java中常用工具类之字符串操作类和MD5加密解密类
- 基于HI600R的差分GPS设搭建过程介绍
- 微信小程序----开发小技巧(二)
- mysql slave是什么_是mysql表里
- hdrp_HDRP:在2019.3版中无法预览
- 【2019年01月18日】股息率分红最高排名
- 开源:Taurus.MVC 框架
- html5QQ浏览器页面引导模板,手机QQ浏览器 策略打造HTML5开放平台
- [ElasticSearch] 空间搜索 (一)
- 单链表的应用---通讯录设计(数据结构课设)
- 泛微e-cology OA 系统远程代码执行漏洞
热门文章
- 特斯拉柏林超级工厂最终环保审批结果有望周五揭晓
- 小米获京东自营安卓平板销量冠军 小米平板5 Pro全版本闪降100元
- 死磕苹果,小米飘了?
- 董明珠“不让加班了”!格力官宣:实行双休,取消加班
- 亿纬锂能:拟参与竞拍兴华锂盐35.2857%股权 挂牌价1.44亿元
- 携程:2021国庆高星酒店均价945元 环比节前一周提升超80%
- iPhone 13系列电池容量最高4350mAh 较iPhone 12提升近20%
- 荣耀50系列完整规格曝光:Vlog至美之作
- 消息称网易云音乐寻求在港上市 或于明年正式IPO
- 华为P50相机新升级:或首发索尼最大底手机CMOS