您当前的位置: 首页 > 

qianbo_insist

暂无认证

  • 0浏览

    0关注

    399博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

qianbo_insist 发布时间:2021-06-09 22:37:00 ,浏览量:0

有关于ssdp安全的文章 ssdp攻击和防御

组播 单播和广播

    组播方式解决了单播情况下数据的重复拷贝及带宽的重复占用,也解决了广播方式下带宽资源的浪费,我们知道单播在发送者和每一接收者之间实现点对点网络连接。如果一台发送者同时给多个的接收者传输相同的数据,也必须相应的复制多份的相同数据包。如果有大量主机希望获得数据包的同一份拷贝时,将导致发送者负担沉重、延迟长、网络拥塞;为保证一定的服务质量需增加硬件和带宽。

    组播在发送者和每一接收者之间实现点对多点网络连接。如果一台发送者同时给多个接收者传输相同的数据,也只需复制一份相同的数据包。它提高了数据传送效率,减少了骨干网络出现拥塞的可能性。实际上,组播在局域网里,是由交换机和路由器等硬件等完成一次数据的存储,而转发给其他的加入组播组的成员的。

地址

    224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用。实际上,这是属于D类地址。 224.0.1.0~238.255.255.255 为用户可用的组播地址(临时组地址),全网范围内有效。

upnp

    plug and play 即插即用协议里面使用的 ssdp(imple Service Discovery Protocol)就是属于组播协议,简单服务发现协议,使用组播地址 239.255.255.255,端口1900 。使用wireshark等该端口的包,是可以看见很多包的,因为网关也使用这一协议。实际上,里面大量充斥的是类http协议,也有ssdp ddos 攻击的可能。

Mbone

    Mbone是一种跨越网络。它是一个相互连接的子网和路由器的集合,这些子网和路由器支持IP组播业务流的传送。作为因特网上的虚拟网络,Mbone通过隧道(Tunneling)来旁路因特网上无组播能力的路由器。但是,不是所有路由器能够支持这种网络,所以,这个只能是实验性质,所以,组播,一般只能在局域网里实现。

如何实现

以下用用实例来说明, c# 和 c++来实现ssdp协议的组播,看似简短,但是以下程序真的是一个小却能使用的ssdp搜索程序,加上tcp的接收和发送,就可以做控制点,凡是有开始,从这个简单的c#程序着手,会有收获。

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace ssdp
{
    class Program
    {
        static void Main(string[] args)
        {
            IPEndPoint LocalEndPoint = new IPEndPoint(IPAddress.Any, 23000);
            IPEndPoint MulticastEndPoint = new IPEndPoint(IPAddress.Parse("239.255.255.250"), 1900);

            Socket UdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            UdpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            UdpSocket.Bind(LocalEndPoint);
            UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(MulticastEndPoint.Address, IPAddress.Any));
            UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 2);
            UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, true);

            Console.WriteLine("UDP-Socket setup done...\r\n");

            string SearchString = "M-SEARCH * HTTP/1.1\r\nHOST:239.255.255.250:1900\r\nMAN:\"ssdp:discover\"\r\nST:ssdp:all\r\nMX:3\r\n\r\n";

            UdpSocket.SendTo(Encoding.UTF8.GetBytes(SearchString), SocketFlags.None, MulticastEndPoint);

            Console.WriteLine("M-Search sent...\r\n");

            byte[] ReceiveBuffer = new byte[3200];

            int ReceivedBytes = 0;

            while (true)
            {
                if (UdpSocket.Available > 0)
                {
                    ReceivedBytes = UdpSocket.Receive(ReceiveBuffer, SocketFlags.None);

                    if (ReceivedBytes > 0)
                    {
                        Console.WriteLine(Encoding.UTF8.GetString(ReceiveBuffer,0, ReceivedBytes));
                    }
                }
            }
        }
    }
}

windows 下 c++组播
/*
* author :qianbo
* function:组播类
* 注意生成对象发送和接收是两个,生成根据 SOKM_REV 还是SOKM_SND
*/

#ifndef __GROUPSOCK_H1_
#define __GROUPSOCK_H1_

#ifdef WIN32
#include 
#include 
#endif


#include 
namespace CorePhone
{
	enum{
      SOCKM_REV,
      SOCKM_SND
	};
#define BUFSIZE 1500

	class CGroupSock
	{
	private:
		
		//以下为第二版多播通信,

		WSADATA             _wsd;
		struct sockaddr_in  _local,
			_remote,
			_from;
		SOCKET              _sock, _sockM;
		int                 _len ;//= sizeof(struct sockaddr_in),
		int                 _optval;
		int                 _ret;

		int _Receive_Send; //(0,1)
	private:
		BOOL _isConnected;
	protected:


		//BOOL InitWinsock2();


	public:
	
		BOOL Initialize(int RS);

		BOOL JoinGroup(const char* ip = NULL,int port = 0);

		BOOL SendTo(const char *pBuf,int nlen);

		 int ReceiveData(char *pBuf,int bufferlen);

	public:
		CGroupSock(void);

		~CGroupSock(void);
	};

};
#endif
/*
Author:钱波
email: 418511899@qq.com
wei:   18091589062
func  :类 windows 下组播
time:  2018年5月30日
*/
#include "GroupSock.h"

namespace CorePhone
{
	

	CGroupSock::CGroupSock(void)
	{
		_len = sizeof(struct sockaddr_in);
	}

	CGroupSock::~CGroupSock(void)
	{
		closesocket(_sock);
	}


	BOOL CGroupSock::Initialize(int RS)
	{
		_Receive_Send = RS;
		return 0;
	}



	BOOL CGroupSock::JoinGroup(const char* ip, int port)
	{

		//
		//以下为第二版windows多播通信,加入了根通信
		if ((_sock = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0,
			WSA_FLAG_MULTIPOINT_C_LEAF
			| WSA_FLAG_MULTIPOINT_D_LEAF
			| WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
		{
			printf("socket failed with: %d\n", WSAGetLastError());
			return FALSE;
		}
		// Bind to the local interface. This is done to receive data.
		_local.sin_family = AF_INET;
		//_local.sin_port   = 0;//htons(port);
		_local.sin_port = 0;
		if (_Receive_Send == SOCKM_REV)
			_local.sin_port = htons(port);

		_local.sin_addr.s_addr = INADDR_ANY;

		char optval = FALSE;    // 屏蔽回播
		if (setsockopt(_sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof(int))             
关注
打赏
1663161521
查看更多评论
0.0380s