OpenHero 开勇

Open heart, bravely fly!

用户操作
[即时聊天] [发私信] [加为好友]
OpenHero 开勇ID:OpenHero
239475次访问,排名270好友198人,关注者210
OpenHero的文章
原创 241 篇
翻译 2 篇
转载 51 篇
评论 476 篇
OpenHero 开勇的公告
有事留言
最近评论
SnowBirdBird:才子....
nicole_yaoyao:家乡,一个可以触及我们心底最柔软地方的词
XiaoG602:谢谢前辈了,正为这个烦呢,能交流一下比赛经验么?谢谢了
qdzhouhanqing:受益匪浅,看过编程手册没太看懂,一看你的文章,真是太形象了,呵呵,学习中~
Evelyn:請問以Wizard產生的cuda dll,可以給vb.net call嗎?我要如何做呢?依照c#例子來寫似乎不可行,謝謝!
文章分类
收藏
    相册
    MetaWeblog API
    相册
    自己
    参与的开源项目
    Scilab Robotics Toolbox
    常去的几个地方
    Robocup 机器人足球官方站点
    RTSJ
    感兴趣的开源项目
    Flash得开源代码
    Robocup server
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 Linux&Windows下的IP Multicast 开发收藏

    新一篇: 一年 | 旧一篇: 太感人了……父爱太伟大了……

     Multicast 不用多说,组播,既然要做multicast开发,肯定得知道multicast是什么;
    windows和linux下开发的multicast的代码如下,具体的讲解,看代码注释:

    C/C++ code
    /*Multicast Client.c support Linux & Windows
    *Zhao.kaiyong(a)gmail.com
    *http://blog.csdn.net/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处理。


    发表于 @ 2008年07月19日 02:20:00|评论(loading...)|收藏

    新一篇: 一年 | 旧一篇: 太感人了……父爱太伟大了……

    评论:没有评论。

    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © OpenHero 开勇