c++ 实现组播协议

64 篇文章 2 订阅
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include <winsock.h>

#pragma comment(lib, "Wsock32.lib")
#define close closesocket

#define LOCAL_IP "0.0.0.0"

typedef int socklen_t;



#define  GROUP_IP	"239.255.0.1"//224.0.0.0-239.255.255.255

#define  PORT		8058



struct sockaddr_in localSock;
struct ip_mreq group;


int GetSOCK_DGRAM(unsigned short port)
{
	int sd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sd < 0)
	{
		perror("Opening datagram socket error");
		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");
	}


	int ret = 0;

	memset((char *)&localSock, 0, sizeof(localSock));
	localSock.sin_family = AF_INET;
	localSock.sin_port = port;
	localSock.sin_addr.s_addr = INADDR_ANY;
	if (bind(sd, (struct sockaddr*)&localSock, sizeof(localSock)))
	{
		perror("Binding datagram socket error");
		close(sd);
		exit(1);
	}
	else
	{
		printf("Binding datagram socket...OK.\n");
	}
	group.imr_multiaddr.s_addr = inet_addr(GROUP_IP);//相当于组名
	group.imr_interface.s_addr = inet_addr(LOCAL_IP);//自己的ip
	if (setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0)
	{
		perror("Adding multicast group error");
		close(sd);
		exit(1);
	}
	else
		printf("Adding multicast 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[])
{
	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];
	while (1)
	{
		nRecvLen = recvfrom(sd, (char*)databuf, recvSize, 0, (struct sockaddr*)&from, (socklen_t*)&fromlen);//read
		if (nRecvLen > 0)
		{
			//	continue;
		}

		printf("recv=%s\n", databuf);

	}

	return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include <winsock.h>

#pragma comment(lib, "Wsock32.lib")
#define close closesocket

#define LOCAL_IP "0.0.0.0"

typedef int socklen_t;



#define  GROUP_IP	"239.255.0.1"  //224.0.0.0-239.255.255.255

#define  PORT		8058



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[])
{
	InitSocket();

	struct in_addr localInterface;
	struct sockaddr_in groupSock;

	char bufSend[BUFSIZ];

	int sd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sd < 0)
	{
		perror("Opening datagram socket error");
		exit(1);
	}
	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);
	localInterface.s_addr = inet_addr(LOCAL_IP);//自己的ip,可以和目标不在一个网,但设置不同的网段。

	//设置组播
	if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, (char *)&localInterface, sizeof(localInterface)) < 0)
	{
		printf("Setting local interface error");
		exit(1);
	}
	else
	{
		printf("Setting the local interface...OK\n");
	}


	for (int i = 0;; i++)
	{
		sprintf(bufSend, "%d", i);
		sendto(sd, bufSend, sizeof(bufSend), 0, (struct sockaddr*)&groupSock, sizeof(groupSock));
		printf("group=%s,locolip=%s,send=%s\n", GROUP_IP, LOCAL_IP, bufSend);
		Sleep(1000);
	}
	return 0;
}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值