WinSock2 IP组播(多播)示例
来源:互联网 发布:python while循环假死 编辑:程序博客网 时间:2024/05/17 02:19
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment( lib, "ws2_32.lib" )
#define MCASTADDR "234.5.6.7"
#define MCASTPORT 25000
#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;
}
Sleep(500);
}
}
closesocket(sock);
WSACleanup();
return -1;
}
这段代码来自《Windows网络编程》第一版中的例子,我做了些简单的处理,例子可以直接执行,方便大家理解和应用Windows组播。
记得我最早接触组播编程是在2002年,但是没有成功,这件事我一直很郁闷,现在呢总算能够游刃有余的驾驭Windows网络编程了,这么多年的汗水和努力总算没有白费。
这段代码中基本比较完整的展示了WinSock2种组播编程的每个方面,包括比较重要的TTL属性和回馈设置等。如果要用于广域网,那么就要注意bind部分的地址,最好是广域网的真实IP,对于使用路由器的,就要对路由器进行设置,对这个端口要放开,同时设置一条路由到服务器的直通路线,建议这种情况下最好配上防火墙,因为这相当于把服务器裸露在广域网上,因此防火墙是必要的。
- WinSock2 IP组播(多播)示例
- WINSOCK2实现IP组播
- IP多播(组播)
- 多播(组播)
- 多播(组播)
- 多播(组播)
- 多播(组播)
- 多播(组播)
- 多播(组播)
- 两个IP组播综合配置示例
- 多播,组播
- 多播、组播
- 多播,组播
- 单播,广播,组播(多播)
- 单播、广播、组播(多播) (摘抄)
- 单播、多播(组播)和广播的
- JAVA 单播、多播(组播)、广播
- winsock 多播(组播)
- 图解java并发(上)
- SQL Server 2005学习笔记之 XML架构
- SQL Server 2005学习笔记之 使用XML架构集合
- WSARecv参数lpNumberOfBytesRecvd的一个变态问题
- 安卓踩坑大全
- WinSock2 IP组播(多播)示例
- php unicode转中文的函数
- 从《亮剑》看先进的管理(原创)
- Darknet (一) YOLO 基于 CentOS CPU 的部署使用
- 我所知道的软件架构
- VC++ 实战OLEDB编程(一)
- windows server2008服务器防火墙配置策略
- VC++ 实战OLEDB编程(二)
- 微博遭鹿晗恋情暴击瘫痪,如何快速提高系统性能?