#include <winsock2.h>
#include <stdio.h>
#include <winsock.h>
#include <Ws2tcpip.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
//#include <Ws2tcpip.h>
//#include <winsock.h>
//#include <ws2ipdef.h>
#pragma comment(lib, "Wsock32.lib")
#define close closesocket
// #define LOCAL_IP "10.65.53.4" // "0.0.0.0"
//
// typedef int socklen_t;
//
//
//
// #define GROUP_IP "239.4.41.72"//224.0.0.0-239.255.255.255
// #define SOURCE_IP "192.168.80.72"
// #define PORT 20101
// struct sockaddr_in localSock;
// struct ip_mreq group;
//
//
//
//
// // typedef struct ip_mreq_source {
// // in_addr imr_multiaddr; // IP multicast address of group.
// // in_addr imr_sourceaddr; // IP address of source.
// // in_addr imr_interface; // Local IP address of interface.
// // };
// //struct ip_mreq_source group;
// // struct igmp
// // {
// // unsigned char igmp_type; /* IGMP type */
// // unsigned char igmp_code; /* routing code */
// // unsigned short igmp_cksum; /* checksum */
// // struct in_addr igmp_group; /* group address */
// // };
//
// // struct igmp_group_record
// // {
// // unsigned char record_type; //组记录类型
// // unsigned char record_Aux_datalen;//辅助数据长度
// // unsigned short record_number_of_group;//组记录中存在多少源地址
// // struct in_addr record_Multicast_Address;//多播IP地址。
// // struct in_addr record_Source_Address;//单播IP地址
// // u_long record_Auxiliary_Data;//辅助数据
// // };
//
//
// // struct igmp_query
// // {
// // unsigned char igmp_type; /* IGMP type */
// // unsigned char igmp_max_resp_time; /* IGMP max resp time */
// // unsigned short igmp_cksum; /* checksum */
// // struct in_addr igmp_group; /* group address */
// // unsigned short igmp_reserved; /* IGMP reserved */
// // unsigned short igmp_group_number; /* group_number */
// // std::vector<igmp_group_record> vigmp_record; /* group record */
// // };
//
// SHORT checksum(USHORT* buffer, int size)
// {
// unsigned long cksum = 0;
// while (size > 1)
// {
// cksum += *buffer++;
// size -= sizeof(USHORT);
// }
// if (size)
// {
// cksum += *(UCHAR*)buffer;
// }
// cksum = (cksum >> 16) + (cksum & 0xffff);
// cksum += (cksum >> 16);
// return (USHORT)(~cksum);
// }
//
//
// int GetSOCK_DGRAM(unsigned short port)
// {
// int sd = socket(AF_INET, SOCK_DGRAM, 0);//SOCK_DGRAM 0
// if (sd < 0)
// {
// int i = WSAGetLastError();
// perror("Opening datagram socket error");
// system("pause");
// exit(1);
// }
// else
// printf("Opening datagram socket....OK.\n");
//
// {
// //设置复用
// int reuse = 1;
// if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
// {
// perror("Setting SO_REUSEADDR error");
// close(sd);
// exit(1);
// }
// else
// printf("Setting SO_REUSEADDR...OK.\n");
// }
//
// // 设置超时
// struct timeval timeout;
// timeout.tv_sec = 1;//秒
// timeout.tv_usec = 0;//微秒
// if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)) == -1)
// {
// perror("setsockopt failed:");
// system("pause");
// }
//
// //绑定
// int ret = 0;
// memset((char *)&localSock, 0, sizeof(localSock));
// localSock.sin_family = AF_INET;
// localSock.sin_port = port;
// localSock.sin_addr.S_un.S_addr = 0;
// if (bind(sd, (struct sockaddr*)&localSock, sizeof(localSock)))
// {
// perror("Binding datagram socket error");
// close(sd);
// system("pause");
// exit(1);
// }
// else
// {
// printf("Binding datagram socket...OK.\n");
// }
// //加入组播
// group.imr_multiaddr.S_un.S_addr = inet_addr(GROUP_IP);//相当于组名
// group.imr_interface.S_un.S_addr = inet_addr(LOCAL_IP);//自己的ip//LOCAL_IP
// // group.imr_sourceaddr.s_addr = inet_addr(SOURCE_IP);//自己的ip
//
// // igmp_query group_igmp;
// // group_igmp.igmp_type = 0x22 ;//成员关系报告
// // group_igmp.igmp_reserved = 0;
// // group_igmp.igmp_cksum = 0;
// // group_igmp.igmp_group.S_un.S_addr = inet_addr(GROUP_IP);//相当于组名
// // group_igmp.igmp_group_number = 1;
// // group_igmp.igmp_max_resp_time = 0;
// // igmp_group_record source;
// // source.record_type = 1;//MODE_IS_INCLUDE
// // source.record_Source_Address.S_un.S_addr = inet_addr(SOURCE_IP);//单播地址
// // source.record_number_of_group = 1;
// // source.record_Aux_datalen = 0;//表示辅助数据不存在
// // source.record_Multicast_Address.S_un.S_addr = inet_addr(GROUP_IP);
// // source.record_Auxiliary_Data = 0;
// // group_igmp.vigmp_record.push_back(source);
// //
// // char bufSend[BUFSIZ];
// // memset(bufSend,0,BUFSIZ);
// // memcpy(bufSend,&group_igmp,sizeof(group_igmp));
// // group_igmp.igmp_cksum = checksum((USHORT*)bufSend,sizeof(group_igmp));
//
// if (setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0)//group IP_ADD_SOURCE_MEMBERSHIP
// {
// perror("Adding multicast group error");
// system("pause");
// close(sd);
// exit(1);
// }
// else
// printf("Adding multicast group...OK.\n");
//
// //设置回环
// char loop = '1';
// if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0)
// {
// perror("Setting loop group error");
// close(sd);
// exit(1);
// }
// else
// printf("Setting loop group...OK.\n");
//
// return sd;
// }
//
// int InitSocket()
// {
// int Error;
// WORD VersionRequested;
// WSADATA WsaData;
// VersionRequested = MAKEWORD(2, 2);
// Error = WSAStartup(VersionRequested, &WsaData); //启动WinSock2
// if (Error != 0)
// {
// return 0;
// }
// else
// {
// if (LOBYTE(WsaData.wVersion) != 2 || HIBYTE(WsaData.wHighVersion) != 2)
// {
// WSACleanup();
// return 0;
// }
// }
// return 0;
// }
//
//
//
// int main(int argc, char *argv[])
// {
// //
// std::vector<ip_mreq> vv;
// ip_mreq temp = {0};
// vv.push_back(temp);
// vv.push_back(temp);
//
// temp.imr_multiaddr.S_un.S_addr = inet_addr(GROUP_IP);//相当于组名
// temp.imr_interface.S_un.S_addr = inet_addr(LOCAL_IP);//自己的ip//LOCAL_IP
// vv.insert(vv.begin()+0,temp);
//
//
// //
// InitSocket();
// int sd = GetSOCK_DGRAM(htons(PORT));
// struct sockaddr_in from;
// int fromlen = sizeof(from);
// int nRecvLen = 1;
// const int recvSize = 1024 * 1000;
// unsigned char* databuf = new unsigned char[recvSize];
// char bufSend[BUFSIZ];
// memset(bufSend,0,BUFSIZ);
//
// // igmp_query group_igmp;
// // group_igmp.igmp_type = 0x22 ;//成员关系报告
// // group_igmp.igmp_reserved = 0;
// // group_igmp.igmp_cksum = 0;
// // group_igmp.igmp_group.S_un.S_addr = inet_addr(GROUP_IP);//相当于组名
// // group_igmp.igmp_group_number = 1;
// // group_igmp.igmp_max_resp_time = 0;
// // igmp_group_record source;
// // source.record_type = 1;//MODE_IS_INCLUDE
// // source.record_Source_Address.S_un.S_addr = inet_addr(SOURCE_IP);//单播地址
// // source.record_number_of_group = 1;
// // source.record_Aux_datalen = 0;//表示辅助数据不存在
// // source.record_Multicast_Address.S_un.S_addr = inet_addr(GROUP_IP);
// // source.record_Auxiliary_Data = 0;
// // group_igmp.vigmp_record.push_back(source);
// //
// //
// // struct sockaddr_in groupSock;
// // memset((char *)&groupSock, 0, sizeof(groupSock));
// // groupSock.sin_family = AF_INET;
// // groupSock.sin_addr.s_addr = inet_addr(GROUP_IP);//GROUP_IP 第一个字节不超过239 后面3个字节用来区别分组 不是掩码
// // groupSock.sin_port = htons(PORT);
// //
// // memcpy(bufSend,&group_igmp,sizeof(group_igmp));
// // group_igmp.igmp_cksum = checksum((USHORT*)bufSend,sizeof(group_igmp));
// //
// // sendto(