只有UDP才能實現多播,TCP/IP不能!
#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define MCASTADDR "239.1.1.1 "
#define MCASTPORT 5000
#define BUFSIZE 1024
#define DEFAULT_COUNT 500
BOOL bSender = FALSE;
BOOL bLoopBack = FALSE ;
DWORD dwInterface,
dwMulticastGroup,
dwCount ;
short iPort ;
DWORD WINAPI my_send(void *);
DWORD WINAPI my_receive(void *);
void usage(char *progname)
{
printf( "example of multicast:%s -s -m:str -p:int -i:str -1 -n:\n ",progname);
}
void ValidateArgs(int argc, char **argv)
{
dwInterface = INADDR_ANY;
dwMulticastGroup = inet_addr(MCASTADDR);
iPort = MCASTPORT ;
dwCount = DEFAULT_COUNT ;
if(tolower(*argv[1]) == 's ')
{
bSender = TRUE ;
}
return ;
}
const int on = 1;
WSADATA wsd;
struct sockaddr_in local,
remote,
from;
char recvbuf[BUFSIZE],
sendbuf[BUFSIZE];
struct ip_mreq mcast;
SOCKET sockM,sockN;
int len = sizeof(struct sockaddr_in),
optval,
ret;
int x = -1;
int main(int argc, char **argv)
{
DWORD i = 0;
DWORD dwThreadId_send = 0;
DWORD dwThreadId_recv = 0;
HANDLE send_Thread = NULL;
HANDLE recv_Thread = NULL;
DWORD dwVesion = 0;
strcpy(sendbuf, "hello ");
ValidateArgs(argc, argv);
if(WSAStartup(MAKEWORD(2,0),&wsd)!=0)
{
printf( "WSAStartup failed\n ");
WSACleanup();
return -1 ;
}
if((sockM = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
printf( "soket failed with: %d\n ", WSAGetLastError());
closesocket(sockM);
WSACleanup();
return -1;
}
if((sockN = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
printf( "soket failed with: %d\n ", WSAGetLastError());
closesocket(sockN);
WSACleanup();
return -1;
}
setsockopt(sockM, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
setsockopt(sockN, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
local.sin_family = AF_INET ;
local.sin_port = htons(iPort) ;
local.sin_addr.S_un.S_addr = dwInterface ;
// printf( "haha\n\n\n\n\nhaha ");
if(bind(sockM,(struct sockaddr *)&local,sizeof(local)) == SOCKET_ERROR)
{
printf( "bind failed ") ;
closesocket(sockM) ;
WSACleanup() ;
return -1 ;
}
if(bind(sockN,(struct sockaddr *)&local,sizeof(local)) == SOCKET_ERROR)
{
printf( "bind failed ") ;
closesocket(sockN) ;
WSACleanup() ;
return -1 ;
}
remote.sin_family = AF_INET ;
remote.sin_port = htons(iPort) ;
remote.sin_addr.S_un.S_addr = dwMulticastGroup ;
mcast.imr_multiaddr.S_un.S_addr = dwMulticastGroup ;
mcast.imr_interface.S_un.S_addr = dwInterface ;
if(setsockopt(sockM, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mcast, sizeof(mcast)) ==SOCKET_ERROR)
{
printf( "setsockopt(IP_ADD_MEMBERSHIP) failed: %d\n: ", WSAGetLastError());
closesocket(sockM);
WSACleanup();
return -1;
}
optval = 8;
if(setsockopt(sockM, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&optval, sizeof(int)) ==SOCKET_ERROR)
{
printf( "setsockopt(IP_MULTICAST_TTL) failed: %d\n: ", WSAGetLastError());
closesocket(sockM);
WSACleanup();
return -1;
}
if(bLoopBack)
{
/* optval = 0;
if(setsockopt(sockM, IPPROTO_IP, IP_MULTICAST_LOOP, (char*)&optval, sizeof(optval)) ==SOCKET_ERROR)
{
printf( "setsockopt(IP_MULTICAST_LOOP) failed: %d\n: ", WSAGetLastError());
closesocket(sockM);
WSACleanup();
return -1;
}
*/ }
send_Thread = CreateThread(
NULL, // default security attributes
0, // use default stack size
my_send, // thread function
NULL, // argument to thread function
0, // use default creation flags
&dwThreadId_send); // returns the thread identifier
recv_Thread = CreateThread(
NULL, // default security attributes
0, // use default stack size
my_receive, // thread function
NULL, // argument to thread function
0, // use default creation flags
&dwThreadId_recv); // returns the thread identifier
x = getch();
CloseHandle( recv_Thread );
CloseHandle( send_Thread );
if(setsockopt(sockM, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)&mcast, sizeof(mcast)) ==SOCKET_ERROR)
{
printf( "setsockopt(IP_DROP_MEMBERSHIP) failed: %d\n: ", WSAGetLastError());
}
closesocket(sockM);
closesocket(sockN);
WSACleanup();
return 0;
}
DWORD WINAPI my_send(void * p)
{
unsigned long i = 0;
for(i=0; i <dwCount; i++)
{ itoa(i,sendbuf,10);
printf( "server 1: This is a test :%s \n ",sendbuf);
if(sendto(sockN, (char*)sendbuf, strlen(sendbuf), 0, (struct sockaddr*)&remote, sizeof(remote)) == SOCKET_ERROR)
{
printf( "sendto failed with : %d\n ",WSAGetLastError());
closesocket(sockN);
WSACleanup();
return -1;
}
Sleep(1000);
}
return 0;
}
DWORD WINAPI my_receive(void * p)
{
unsigned long i = 0;
for(i = 0; i <dwCount; i++)
{
Sleep(500);
memset(recvbuf,0,BUFSIZE);
if((ret = recvfrom(sockM, recvbuf, BUFSIZE, 0, (struct sockaddr *)&from, &len)) == SOCKET_ERROR)
{
printf( "recvfrom failed with: %d\n: ", WSAGetLastError());
printf( "sdf\n ");
closesocket(sockM);
WSACleanup();
return -1;
}
printf( "RECV: '%s ' from <%s> \n ", recvbuf ,inet_ntoa(from.sin_addr));
}
return 0;
}