/*
* 转载
*/
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment( lib, "ws2_32.lib" )
#define MCASTADDR "234.0.0.5"
#define MCASTPORT 7000
#define BUFSIZE 1024
#define DEFAULT_COUNT 500
BOOL bSender = FALSE,
bLoopBack = FALSE;
DWORD dwInterface,dwMulticastGroup,dwCount;
short iPort;
void usage(char *progname)
{
printf("usage: %s -s -m:str -p:int -i:str -l -n:int/n",progname);
printf(" -s Act as server (send data);otherwise/n");
printf(" receive data./n");
printf(" -m:str Dotted decimal multicast IP address to join/n");
printf(" The default group is: %s/n",MCASTADDR);
printf(" -p:int Port number to use/n");
printf(" The default port is: %d/n",MCASTPORT);
printf(" -i:str Local interface to bind to; by default/n");
printf(" use INADDRY_ANY/n");
printf(" -l Disable loopback/n");
printf(" -n:int Number of messages to send/receive/n");
ExitProcess(-1);
}
void ValidateArgs(int argc,char** argv)
{
int i;
dwInterface = INADDR_ANY;
dwMulticastGroup = inet_addr(MCASTADDR);
iPort = MCASTPORT;
dwCount = DEFAULT_COUNT;
for(i = 1; i < argc; i++)
{
if(( argv[i][0] == '-') || (argv[i][0] == '/'))
{
switch(tolower(argv[i][1]))
{
case 's':
bSender = TRUE;
break;
case 'm':
if( strlen(argv[i]) > 3 )
dwMulticastGroup = inet_addr(&argv[i][3]);
break;
case 'i':
if( strlen(argv[i]) > 3)
dwInterface = inet_addr(&argv[i][3]);
break;
case 'p':
if ( strlen(argv[i]) > 3)
iPort = atoi(&argv[i][3]);
break;
case 'l':
bLoopBack = TRUE;
break;
case 'n':
dwCount = atoi(&argv[i][3]);
break;
default:
usage(argv[0]);
break;
}
}
}
return;
}
int main(int argc,char **argv)
{
WSADATA wsd;
struct sockaddr_in local,remote,from;
SOCKET sock,sockM;
char recvbuf[BUFSIZE],sendbuf[BUFSIZE];
int len = sizeof(struct sockaddr_in),optval,ret;
DWORD i = 0;
ValidateArgs(argc,argv);
if(WSAStartup(MAKEWORD(2,2),&wsd) != 0)
{
printf("WSAStartup() Failed/n");
return -1;
}
if(( sock = WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,
WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF
|WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("socket failed with: %d/n",WSAGetLastError());
WSACleanup();
return -1;
}
local.sin_family = AF_INET;
local.sin_port = htons(iPort);
local.sin_addr.s_addr = dwInterface;
if( bind(sock,(struct sockaddr * )&local,sizeof(local) ) == SOCKET_ERROR)
{
printf("bind failed with: %d/n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
remote.sin_family = AF_INET;
remote.sin_port = htons(iPort);
remote.sin_addr.s_addr = dwMulticastGroup;
optval = 8;
if( setsockopt(sock,IPPROTO_IP,IP_MULTICAST_TTL,
(char*)&optval,sizeof(int)) == SOCKET_ERROR)
{
printf("setsockopt(IP_MULTICAST_TTL) failed: %d/n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
if( bLoopBack )
{
optval = 0;
if( setsockopt(sock,IPPROTO_IP,IP_MULTICAST_LOOP,
(char*)& optval,sizeof(optval)) == SOCKET_ERROR)
{
printf("setsockopt(IP_MULTICAST_LOOP) failed: %d/n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
}
if( (sockM = WSAJoinLeaf(sock,(SOCKADDR*)&remote,
sizeof(remote),NULL,NULL,NULL,NULL,JL_BOTH)) == INVALID_SOCKET)
{
printf("WSAJoinLeaf() failed: %d/n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
if(!bSender)
{
for(i = 0; i < dwCount; i++)
{
if((ret = recvfrom(sock,recvbuf,BUFSIZE,0,(struct sockaddr*)&from,&len)) == SOCKET_ERROR)
{
printf("recvfrom failed with: %d/n",WSAGetLastError());
closesocket(sockM);
closesocket(sock);
WSACleanup();
return -1;
}
recvbuf[ret] = 0;
printf("RECV: '%s' from <%s>/n",recvbuf,inet_ntoa(from.sin_addr));
}
}
else
{
for(i = 0; i < dwCount; i ++)
{
sprintf(sendbuf,"server 1:This is a test:%d",i);
if(sendto(sock,(char*)sendbuf,strlen(sendbuf),0,(struct sockaddr*)&remote,sizeof(remote)) == SOCKET_ERROR)
{
printf("sendto failed with: %d/n",WSAGetLastError());
closesocket(sockM);
closesocket(sock);
WSACleanup();
return -1;
}
printf("send out!/n");
Sleep(500);
}
}
closesocket(sock);
WSACleanup();
return -1;
}
本文提供了一个使用Winsock在Windows环境下实现组播通信的C语言程序示例。该示例展示了如何设置发送者和接收者,配置组播地址、端口及接口,并通过命令行参数来定制通信行为。
145

被折叠的 条评论
为什么被折叠?



