在windows 下用C实现的一个多播的简单例子

/* 编译通过环境,Windows XP sp2,Windows 2003 server SDK,VC++6.0 sp5. */ 

/************************************************************************
* File: UDP group broadcast header file
* Author: WenXiaoyong,Wen_kernel@163.com
* Copyright: (C) WenXiaoyong,2007
*                                                                   
************************************************************************/

#ifndef UDP_GROUP_BROADCAST_H
#define UDP_GROUP_BROADCAST_H


#include <stdio.h>
#include <Winsock2.h>
#include <Ws2tcpip.h>
#include <stdlib.h>
#pragma comment(lib, "Ws2_32.lib")


/* define microes */


/* declare extern variables */
extern SOCKET gServerSocket;
extern SOCKET gClientSocket;
extern char gServerIP[];
extern char gClientIP[];


/* declare functions */
/* server */
int CreatServerUDPSocket(SOCKET *pServerSocket, char chServerIP[], /
	unsigned short uPort);
int SetSocketOption(SOCKET *pServerSocket, int nLevel,/
	int nOptname, const char FAR *pOptval, int nOptlen);
int SendTo(SOCKET *pServerSocket, char *pBuff, int nOffset, int nLen);


/* client */
int CreatClientUDPSocket(SOCKET *pClientSocket, char chClientIP[], /
	unsigned short uPort);
int ReciveFrom(SOCKET *pSocket, char pBuff[], int nOffset, int nLen);



#endif /* UDP_GROUP_BROADCAST_H */
/************************************************************************
* File: main funtion file
* Author: WenXiaoyong,Wen_kernel@163.com
* Copyright: (C) WenXiaoyong,2007
*                                                                   
************************************************************************/


#include "E:/MyDevLib/Windows/UDP_GroupBroadcast.h"
#include <error.h>
#include <assert.h>


/* define microes */
#define MAX_REC_BUFF_LEN 128
#define TIME_SLEEP 100 /* milliseconds */
#define PORT_UDP 1225


/* main function */
int main( int argc, char *argv[], char *envp[])
{
	long lCount;
	int nReturn;
	char chRecBuff[MAX_REC_BUFF_LEN];
	const int nOn = 1; /* 允许程序的多个实例运行在同一台机器上 */
	int nReciveCount;

	/* config IP */
	if(argc == 2)
	{
		memcpy(gClientIP, argv[1], strlen(argv[1]));
		printf("Note: config IP[%s]./n", argv[1]);
	}

	/* creat a UDP socket */
	nReturn = CreatClientUDPSocket(&gClientSocket, gClientIP, PORT_UDP);
	if(!nReturn)
	{
		printf("Note: creat a client UDP socket OK./n");
	}
	else 
	{
		printf("Error: creat a client UDP socket was failed! [error=%d]/n", nReturn);
		goto error_exit;
	}

	/* recive data */
	printf("Note: beginning recive data .../n");
	lCount = 1;
	nReciveCount = 15;
	while(1)
	{
		memset(chRecBuff, 0, sizeof(chRecBuff));
		nReturn = ReciveFrom(&gClientSocket, chRecBuff, 0, sizeof(chRecBuff));
		if (!nReturn)
		{ 
			printf("Note: recived data[%s]./n", chRecBuff);
		}
		else
		{
			printf("Error: recive data was failed! [error=%d]/n", WSAGetLastError());
			goto error_exit;
		}

		Sleep(TIME_SLEEP);
	}


error_exit:
	closesocket(gClientSocket);
	WSACleanup();
	printf("Note: process exit./n");
	return 0;
}
/************************************************************************
* File: main funtion file
* Author: WenXiaoyong,Wen_kernel@163.com
* Copyright: (C) WenXiaoyong,2007
*                                                                   
************************************************************************/

#include "E:/MyDevLib/Windows/UDP_GroupBroadcast.h"
#include <error.h>
#include <assert.h>


/* define microes */
#define MAX_SEND_BUFF_LEN 128
#define TIME_SLEEP 100 /* milliseconds */
#define PORT_UDP 1225


/* main function */
int main( int argc, char *argv[], char *envp[])
{
	long lCount;
	int nReturn, nSendFlag;
	char chSendBuff[MAX_SEND_BUFF_LEN];

	memset(chSendBuff, 0, sizeof(chSendBuff));

	/* config IP */
	if(argc == 2)
	{
		memcpy(gServerIP, argv[1], strlen(argv[1]));
		printf("Note: config IP[%s]./n", argv[1]);
	}
	/* creat a UDP socket */
	nReturn = CreatServerUDPSocket(&gServerSocket, gServerIP, PORT_UDP);
	if(!nReturn)
	{
		printf("Note: creat server UDP socket OK./n");
	}
	else
	{
		printf("Error: creat server UDP socket was failed! [error=%d]/n", nReturn);
		goto error_exit;
	}

	printf("Note: beginning send data .../n");

	lCount = 1;
	nSendFlag = 0x8;
	while(/*nSendFlag*/1)
	{
		/* send some datas */
		nSendFlag = lCount != 0xf;
		sprintf(chSendBuff, "Wenxy test %d", lCount++);
		nReturn = SendTo(&gServerSocket, chSendBuff, 0, strlen(chSendBuff));
		if(!nReturn)
		{
			printf("Note: send data [%s]./n", chSendBuff);
		}
		else
		{
			printf("Error: send data was failed! [error=%d]/n", nReturn);
			goto error_exit;
		}
		Sleep(TIME_SLEEP);
	}


error_exit:
	closesocket(gServerSocket);
	WSACleanup();
	printf("Note: process exit./n");
	return 0;
}


/************************************************************************
* File: UDP group broadcast implement file
* Author: WenXiaoyong,Wen_kernel@163.com
* Copyright: (C) WenXiaoyong,2007
*                                                                   
************************************************************************/


#include "UDP_GroupBroadcast.h"


/* define microes */
#define PORT_UDP_SERVER 1225
#define IP_SERVER  "192.168.1.125" 
#define IP_MULTICAST  "224.0.0.99" /* 多播地址 */
#define MAX_IP_LEN 16

/* globals variables */
SOCKET gServerSocket, gClientSocket;
char gServerIP[MAX_IP_LEN]; 
char gClientIP[MAX_IP_LEN];
struct sockaddr_in gServerAddr;
struct sockaddr_in gClientAddr;


/* functions */
int CreatServerUDPSocket(SOCKET *pServerSocket, char chServerIP[], /
	unsigned short uPort)
{
	unsigned long ulOptval;
	unsigned short uVersionRequested;
	WSADATA wsaData;
	struct ip_mreq mreq;
	const int nOn = 1; /* 允许程序的多个实例运行在同一台机器上 */
	const int nRouteTTL = 10;
	const int loopback = 0; /* 禁止回馈 */

	uVersionRequested = MAKEWORD(2, 2);

	if(0 != WSAStartup(uVersionRequested, &wsaData))
	{
		return WSAGetLastError();
	}

	*pServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
	if(INVALID_SOCKET == *pServerSocket)
	{
		WSACleanup();
		return WSAGetLastError(); 
	}

	/* allow rebind for other instance */
#if 0
	if(SOCKET_ERROR == setsockopt(*pServerSocket, SOL_SOCKET, /
		SO_REUSEADDR, (char *)&nOn, sizeof(nOn)))
	{
		closesocket(*pServerSocket);
		WSACleanup();
		return WSAGetLastError();
	}
#endif

	/* set route TTL */
	if(SOCKET_ERROR == setsockopt(*pServerSocket, IPPROTO_IP, IP_MULTICAST_TTL, /
		(char *)&nRouteTTL, sizeof(nRouteTTL)))
	{
		closesocket(*pServerSocket);
		WSACleanup();
		return WSAGetLastError();
	}

	/* no loop back */
	if(SOCKET_ERROR == setsockopt(*pServerSocket, IPPROTO_IP, IP_MULTICAST_LOOP, /
		(char*)&loopback, sizeof(loopback)))
	{
		closesocket(*pServerSocket);
		WSACleanup();
		return WSAGetLastError();
	}

	/* bind */
	memset(&gServerAddr, 0, sizeof(struct sockaddr_in));
	gServerAddr.sin_family = AF_INET;
	gServerAddr.sin_addr.s_addr = inet_addr(chServerIP); /* INADDR_ANY; */
	gServerAddr.sin_port = htons(uPort);
	if(SOCKET_ERROR == bind(*pServerSocket, &gServerAddr, sizeof(gServerAddr)))
	{
		closesocket(*pServerSocket);
		WSACleanup();
		return WSAGetLastError();
	}


	/* join a group of multicast */
	memset(&mreq, 0, sizeof(mreq));
	mreq.imr_interface.S_un.S_addr = inet_addr(chServerIP);
	mreq.imr_multiaddr.S_un.S_addr = inet_addr(IP_MULTICAST); 

	if(SOCKET_ERROR == setsockopt(*pServerSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,/
		&mreq, sizeof(mreq)))
	{
		closesocket(*pServerSocket);
		WSACleanup();
		return WSAGetLastError();
	}

	return 0;
}


int SetSocketOption(SOCKET *pSocket, int nLevel,/
	int nOptname, const char FAR *pOptval, int nOptlen)
{
	if(SOCKET_ERROR == setsockopt(*pSocket, nLevel, /
		nOptname, pOptval, nOptlen))
	{
		return WSAGetLastError();
	}
	return 0;
}


int ReciveFrom(SOCKET *pSocket, char pBuff[], int nOffset, int nLen)
{
	struct sockaddr_in ClientAddr;
	int nReturn = 0, nAddrLen;
	memset(&ClientAddr, 0, sizeof(struct sockaddr_in));

	nAddrLen = sizeof(ClientAddr);
	nReturn = recvfrom(*pSocket, pBuff, nLen, /
		0, (struct sockaddr *)&ClientAddr, &nAddrLen);
#if 0
	memcpy(pBuff, "wenxy", sizeof("wenxy"));
	nReturn = 5;
#endif
	if(nReturn == SOCKET_ERROR)
	{
		return -1;
	}
	return 0;
}


int SendTo(SOCKET *pServerSocket, char *pBuff, int nOffset, int nLen)
{
	int nSendLen;
	struct sockaddr_in remote;

	memset(&remote, 0, sizeof(remote));
	remote.sin_addr.s_addr = inet_addr ( IP_MULTICAST );
	remote.sin_family = AF_INET;
	remote.sin_port = htons(PORT_UDP_SERVER);

	nSendLen = sendto(*pServerSocket, pBuff, nLen, 0, /
		(struct sockaddr *)&remote, sizeof(remote));
	if(nSendLen <= 0)
	{
		return WSAGetLastError();
	}
	return 0;
}


/************************************************************************/
/* client functions */

int CreatClientUDPSocket(SOCKET *pClientSocket, char chClientIP[], /
	unsigned short uPort)
{
	unsigned long ulOptval;
	unsigned short uVersionRequested;
	WSADATA wsaData;
	struct ip_mreq mreq;
	const int nOn = 1;
	uVersionRequested = MAKEWORD(2, 2);

	if(0 != WSAStartup(uVersionRequested, &wsaData))
	{
		return WSAGetLastError();
	}

	*pClientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
	if(INVALID_SOCKET == *pClientSocket)
	{
		closesocket(*pClientSocket);
		WSACleanup();
		return WSAGetLastError(); 
	}

#if 0
	/* set socket option */
	if(SOCKET_ERROR == setsockopt(*pClientSocket, SOL_SOCKET, /
		SO_REUSEADDR, (char *)&nOn, sizeof(nOn)))
	{
		closesocket(*pClientSocket);
		WSACleanup();
		return WSAGetLastError();
	}
#endif

#if 1
	/* bind */
	memset(&gClientAddr, 0, sizeof(gClientAddr));
	gClientAddr.sin_family = AF_INET;
	gClientAddr.sin_addr.s_addr = inet_addr(chClientIP);
	gClientAddr.sin_port = htons( uPort ); 
	if(SOCKET_ERROR == bind(*pClientSocket, &gClientAddr, sizeof(gClientAddr)))
	{
		closesocket(*pClientSocket);
		WSACleanup();
		return WSAGetLastError();
	}
#endif

	/* join a group of multicast */
	memset(&mreq, 0, sizeof(mreq));
	mreq.imr_interface.S_un.S_addr = inet_addr(chClientIP);
	mreq.imr_multiaddr.S_un.S_addr = inet_addr(IP_MULTICAST); 

	if(SOCKET_ERROR == setsockopt(*pClientSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,/
		&mreq, sizeof(mreq)))
	{
		closesocket(*pClientSocket);
		WSACleanup();
		return WSAGetLastError();
	}

	return 0;
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值