Linux&Windows下的IP Multicast 开发

 Multicast 不用多说,组播,既然要做multicast开发,肯定得知道multicast是什么;
windows和linux下开发的multicast的代码如下,具体的讲解,看代码注释:
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
C/C++ code
/*Multicast Client.c support Linux & Windows
*Zhao.kaiyong(a)gmail.com
*http://blog.youkuaiyun.com/openhero
*可以转载,可以复制,修改,如果有修改,请给我来一封email:)谢谢
*/

#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>

#ifdef _WIN32
#include
<winsock2.h>
#include
<io.h>
#include
<Ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib")

#else
#include
<sys/types.h>
#include
<sys/socket.h>
#include
<netinet/in.h>
#include
<arpa/inet.h>
#include
<unistd.h>
#include
<errno.h>
#define closesocket close
#endif

#define BUF_SIZE 0x1000

char * host_name = "224.1.1.3";
int port = 12345;

int main(int argc, char* argv[])
{
int loop = 1;
/* 多播循环 */
int iter = 0;
int from_len;
char buffer[BUF_SIZE];
int socket_descriptor;
struct ip_mreq command;
struct sockaddr_in loc;
struct sockaddr_in rem;

int rec_len =0;
int ptr_point = 0;
size_t bytes_written
= 0;
int loop_times = 0;

int rcv_port_0 = 0;
int rcv_port_1 = 0;
int first = 0;

#ifdef _WIN32
WSADATA wsaData;

if( WSAStartup(MAKEWORD(2,2), &wsaData) != 0 )
{
printf(
"Error in WSAStartup/n");
exit(
1);
}
#endif

if (argv[1])
{
host_name
= argv[1];
printf(
"%s /n", host_name);
}
if (argv[2])
{
port
= atoi(argv[2]);
printf(
"%d /n", port);
}

memset(
&loc, 0, sizeof(loc));
loc.sin_family
= AF_INET;
//这个地方很重要,不然linux下就只能是broadcast;所以必须指定组播的地址;
loc.sin_port = htons(port);
loc.sin_addr.s_addr = inet_addr(host_name);

if((socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror(
"socket");
exit(EXIT_FAILURE);
}

/*can use the same port in the pc*/
loop
= 1;
if(setsockopt(socket_descriptor, SOL_SOCKET, SO_REUSEADDR, &loop, sizeof(loop)) < 0)
{
perror(
"setsockopt:SO_REUSEADDR./n");
exit(EXIT_FAILURE);
}
else
{
printf(
"setsockopt:SO_REUSEADDR./n");
}
loop
= 0x1000000;// 设置网络的接收buffer的大小
if( setsockopt( socket_descriptor, SOL_SOCKET, SO_RCVBUF, (void *) &loop, sizeof( loop ) ) < 0 )
{
perror(
"setsockopt:SO_RCVBUF./n");
exit(EXIT_FAILURE);
}
//由于在前面指定了组播的地址,但是在winodws和linux下不一样,就得这么处理,这个细节来之分析VLC源代码
#if defined( WIN32 ) || defined( UNDER_CE )
/*
* Under Win32 and for multicasting, we bind to INADDR_ANY.
* This is of course a severe bug, since the socket would logically
* receive unicast traffic, and multicast traffic of groups subscribed
* to via other sockets. How this actually works in Winsock, I don't
* know.
*/
if( IN_MULTICAST( ntohl( loc.sin_addr.s_addr ) ) )
{
struct sockaddr_in stupid = loc;
stupid.sin_addr.s_addr
= INADDR_ANY;

if( bind( socket_descriptor, (struct sockaddr *)&stupid, sizeof( stupid ) ) < 0 )
{
perror(
"bind socket./n");
close( socket_descriptor );
return 0;
}
}
else
#endif
if(bind(socket_descriptor, (struct sockaddr *)&loc, sizeof(loc)) < 0)
{
perror(
"bind socket./n");
exit(EXIT_FAILURE);
}



{ //加入组播组,如果有多块网卡,可以用另一个变量来特别设置;
printf(
"%s,%d/n", host_name, port);
command.imr_multiaddr.s_addr
= inet_addr(host_name);
command.imr_interface.s_addr
= htonl(INADDR_ANY);
if(command.imr_multiaddr.s_addr == -1)
{
perror(
"224.1.1.3 not a legal multicast address./n");
exit(EXIT_FAILURE);
}
if (setsockopt(socket_descriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP, &command, sizeof(command)) < 0)
{
perror(
"setsockopt:IP_ADD_MEMBERSHIP. error/n");
}
}


printf(
"start reciving.../n");


from_len
= sizeof(rem);
while(1)
{
memset(
&rem, 0, from_len);
memset(buffer,
0, BUF_SIZE);
if( (rec_len = recvfrom(socket_descriptor, buffer, sizeof(char) * BUF_SIZE, 0, (struct sockaddr *)&rem, &from_len)) == -1) {
perror(
"recvfrom./n");
}

printf(
"From host:%s port:%d, len: %d/n", inet_ntoa(rem.sin_addr), ntohs(rem.sin_port), rec_len);
}
if(setsockopt(socket_descriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP, &command, sizeof(command)) < 0) {
perror(
"setsockopt:IP_DROP_MEMBERSHIP./n");
}
closesocket(socket_descriptor);
exit(EXIT_SUCCESS);
}
注:
1.在windows中不需要特殊的设置网络;
2.在Linux下得特别注意网络的设置,有下面几个环节:
1)查看内核模块,是否已经加载了multicast支持;这个可以通过 在src目录下面 make menuconfig 查看ip 设置栏目看到;
2)查看网络是否已经加载了multicast支持;命令:ip a 可以看到现在网络支持的各个功能;
3)添加multicast 网络路由:net add -net 224.0.0.0 netmask 240.0.0.0 dev eth0
这样才能启动网络的multicast路由支持,不然只能当作broadcast处理。


评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值