要想接收到多播包,必须先加入多播组(224.0.0.1 ~239. 255.255.255)。但是总可以发送多播包,无论加入与否。另外一般的以太网PHY+MAC芯片都有一个Receive Control Register(RCR),里面可以设置是否接收所有的Multicast包(甚至是Promiscuous模式)还是根据Multicast Table来接收。
接收多播包
-----------------
#include "stdafx.h"
#include <winsock2.h>
#include <ws2tcpip.h>
int MulticastTask()
{
int i = 0;
WSADATA wsaData;
SOCKET Sock = INVALID_SOCKET; // Datagram window socket
struct ip_mreq mreq; // Used in adding or dropping
struct sockaddr_in sLocalAddr;
struct sockaddr_in sClientAddr;
UINT32 lSockAddrSize;
BYTE buf[100];
int dataLength;
if (WSAStartup (MAKEWORD(1, 1), &wsaData) != 0)
return 0;
// Create a datagram socket, Sock.
if ((Sock = socket (AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
return 0;
// Fill out the local socket's address information.
sLocalAddr.sin_family = AF_INET;
sLocalAddr.sin_port = htons (3333);
sLocalAddr.sin_addr.s_addr = htonl (INADDR_ANY);
// Associate the local address with Sock.
if (bind (Sock, (struct sockaddr FAR *) &sLocalAddr, sizeof (sLocalAddr)) == SOCKET_ERROR)
{
closesocket (Sock);
return 0;
}
// Join the multicast group from which to receive datagrams.
mreq.imr_multiaddr.s_addr = inet_addr ("224.1.1.1"); //
mreq.imr_interface.s_addr = INADDR_ANY;
lSockAddrSize = sizeof( struct sockaddr_in );
if (setsockopt (Sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR *)&mreq, sizeof (mreq)) == SOCKET_ERROR)
return 0;
for (; ;)
{
lSockAddrSize = sizeof(sClientAddr);
memset(&sClientAddr, 0, lSockAddrSize);
dataLength = recvfrom(Sock, (char*)buf, 100, 0,
( struct sockaddr * ) & sClientAddr, &lSockAddrSize);
if (( dataLength == 0 ) || ( dataLength == SOCKET_ERROR ))
continue;
}
closesocket (Sock);
WSACleanup ();
return 1;
}
发送多播包(前面与发送基本一样,但不用加入组)
------------------------------------------------------------------------
dest_sin.sin_family = AF_INET;
dest_sin.sin_port = htons (DESTINATION_PORT);
dest_sin.sin_addr.s_addr = inet_addr (DEST_MCAST);
sendto (Sock, szMessage, strlen (szMessage) + 1, 0, (struct sockaddr FAR *) &dest_sin, sizeof (dest_sin));