在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;
}

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值