关于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(二)相关推荐

  1. 关于socket组播和ssdp(一)[修改1.2]

    有关于ssdp安全的文章 ssdp攻击和防御 组播 单播和广播 组播方式解决了单播情况下数据的重复拷贝及带宽的重复占用,也解决了广播方式下带宽资源的浪费,我们知道单播在发送者和每一接收者之间实现点对点 ...

  2. asio 组播包ssdp

    asio 组播ssdp 注意:低版本的asio lib必须要加入预定义 ASIO_STANDALONE 上次写了一个boost加入组播的代码,这次我们不在使用boost,直接使用asio 1.加入组播 ...

  3. 三种组播×××承载方案对比

    方案一:基于PIM-SM/mGRE的承载方案 如图所示,公网运行PIM-SM协议,且PE 1.PE2和PE 3都支持mVRF实例. 不同的mVRF站点加入到同一个组播域(MD)中,通过MD内自动建立的 ...

  4. IP组播基础(一)点到多点应用特点、组播基本架构、组播IP、MAC地址结构组成

    文章目录 前言 点到多点应用的发展与部署 传统点到点应用 点到多点应用 用单播方式部署点到多点应用 用广播的方式部署点到多点网络 组播方式部署点到多点应用 组播基本概述 组播基本架构 组播源到路由器 ...

  5. IP组播技术在视频中的应用(1)

    IP组播技术在视频中的应用(1) IP组播技术在视频中的应用 摘要:随着流媒体.视频等业务在 Internet 上的相继开展, IP 组播技术和应用开始快速发展.本文主要分析 IP 组播技术的产生.概 ...

  6. UDP协议、广播、组播和多路复用(网络编程二)

    一.udp通信 1. 基本流程 udp发送端 udp接收端 socket() socket() bind(); bind(); sendto/recvfrom sendto/recvfrom clos ...

  7. JAVA 网络编程(5) SOCKET UDP 单播和组播,以及组播其他机器收不到报文的解决方法

    UDP既可以单播也可以组播 一,单播 单播的过程为 发送方: InetAddress destAddr = InetAddress.getByName("192.168.4.199" ...

  8. 网络编程-Socket套接字(TCP、UDP、广播和组播通信)

    socket套接字 socket是一个编程接口(网络编程接口) 作用是用来实现网络上不同的主机的应用进程之间进行双向通信 套接字是一种特殊的文件描述符 也就意味着我们使用套接字实现网络通信的时候可以用 ...

  9. Socket网络编程之组播实现(C++,Rust)

    实际项目中,经常需要使用组播,代码示例如下: 一.C++实现(Windows) 服务端源码 服务端需要添加加入组播组的相关代码. #include "stdafx.h" #incl ...

最新文章

  1. 读书:个人成长 -- 即兴演讲
  2. 为数字资产交易设计安全的钱包架构
  3. wifi boombox android,android filament入门,GLB和GLTF模型查看器
  4. 【2020蓝桥杯】Python组真题解析 - 第十一届蓝桥杯
  5. Bookshelf 2
  6. js 字符串插入_前端利器React,为什么推荐JSX来替换JS
  7. 调用微信支付接口总结
  8. Android so减包相关
  9. 一份来自滴滴运维工程师的监控系统建设心得
  10. md5加解密工具 java_java中常用工具类之字符串操作类和MD5加密解密类
  11. 基于HI600R的差分GPS设搭建过程介绍
  12. 微信小程序----开发小技巧(二)
  13. mysql slave是什么_是mysql表里
  14. hdrp_HDRP:在2019.3版中无法预览
  15. 【2019年01月18日】股息率分红最高排名
  16. 开源:Taurus.MVC 框架
  17. html5QQ浏览器页面引导模板,手机QQ浏览器 策略打造HTML5开放平台
  18. [ElasticSearch] 空间搜索 (一)
  19. 单链表的应用---通讯录设计(数据结构课设)
  20. 泛微e-cology OA 系统远程代码执行漏洞

热门文章

  1. 特斯拉柏林超级工厂最终环保审批结果有望周五揭晓
  2. 小米获京东自营安卓平板销量冠军 小米平板5 Pro全版本闪降100元
  3. 死磕苹果,小米飘了?
  4. 董明珠“不让加班了”!格力官宣:实行双休,取消加班
  5. 亿纬锂能:拟参与竞拍兴华锂盐35.2857%股权 挂牌价1.44亿元
  6. 携程:2021国庆高星酒店均价945元 环比节前一周提升超80%
  7. iPhone 13系列电池容量最高4350mAh 较iPhone 12提升近20%
  8. 荣耀50系列完整规格曝光:Vlog至美之作
  9. 消息称网易云音乐寻求在港上市 或于明年正式IPO
  10. 华为P50相机新升级:或首发索尼最大底手机CMOS