Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1676140
  • 博文数量: 311
  • 博客积分: 7778
  • 博客等级: 少将
  • 技术积分: 4186
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-09 19:59
个人简介

蓝点工坊(http://www.bluedrum.cn) 创始人,App和嵌入式产品开发。同时也做相应培训和外包工作。 详细介绍 http://pan.baidu.com/s/1y2g88

文章存档

2012年(3)

2011年(115)

2010年(170)

2009年(23)

分类: 系统运维

2010-10-13 01:26:07


服务器代码


/*
  UDP MultiCast Echo Server
   Author :Andrew Huang

 
 */


#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>

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

#include <pthread.h>


static int listen_fd = -1;

void exit_handler(int no)
{
   close(listen_fd);
    exit(0);
}


/* 加入某个主播组 */
int add_multicast_group(int udp_fd,char * mgroup_ip)
{
   struct ip_mreq multi_req;


    multi_req.imr_multiaddr.s_addr = inet_addr(mgroup_ip);

    multi_req.imr_interface.s_addr = htonl(INADDR_ANY);

    if (-1 == setsockopt(udp_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&multi_req,
sizeof(multi_req)))
    {
       perror("setsockopt_multi");
       return -1;
    }


  return 0;

}

void * echo_thread(void * arg)
{
  int client_fd = (int)arg;
 int len;
 char buffer[1024];

     struct sockaddr_in local_addr;
   struct sockaddr_in peer_addr;
     socklen_t sockaddr_len = sizeof(struct sockaddr_in);

  
    if(getsockname(client_fd,(struct sockaddr *)&local_addr,&sockaddr_len)!= 0)
        {
             perror("getsockname");
        }

   fprintf(stdout,"local addr %s:%d\n",inet_ntoa(local_addr.sin_addr),ntohs(local_addr.sin_port));
   
     
    while(1)
      {
         len = recvfrom(client_fd,buffer,sizeof(buffer),0,(struct sockaddr *)&peer_addr,&sockaddr_len);
               

        if(len <= 0)
                   goto EXIT_THREAD;
            

        if(strncmp("exit",buffer,4)==0)
                      goto EXIT_THREAD;


                  sendto(client_fd,buffer,len,0,(struct sockaddr *)&peer_addr,sockaddr_len);

                
             }

EXIT_THREAD:
             fprintf(stdout,"thread %d exit\n",client_fd);
             close(client_fd);
}



int main(int argc,char * argv[])
{
   unsigned short port = 9000;
   
     char buffer[1024];
      char group_ip[64] ="224.0.0.1";
      int len;


    signal(SIGTERM,exit_handler);
    signal(SIGINT,exit_handler);

   
    struct sockaddr_in server_addr;
     struct sockaddr_in client_addr;
    socklen_t sockaddr_len = sizeof(struct sockaddr_in);

   if(argc > 1)
      port = (unsigned short)atoi(argv[1]);

 
   if(argc > 2)
      strncpy(group_ip,argv[2],sizeof(group_ip)-1);



   /* 第一步:创建UDP SOCKET*/
    listen_fd = socket(PF_INET,SOCK_DGRAM,0);
     if(listen_fd == -1)
       {
          perror("socket");
       }

  {
   int reuse=1;
  if(setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,(const char*)&reuse,sizeof(int))!= 0){
                perror("setsockopt");
             }


    }


   if(add_multicast_group(listen_fd,group_ip)!= 0)
       {
            perror("add_group");
               exit(-1);
       }

   /* 第二步:设置侦听端口 */
      server_addr.sin_family = AF_INET ; /* ipv4 */
      server_addr.sin_port = htons(port);
       server_addr.sin_addr.s_addr = INADDR_ANY;

      if(bind(listen_fd,(struct sockaddr *)&server_addr,sockaddr_len)!=0)
        {
           perror("bind");
           exit_handler(0);
             
         }

     

       fprintf(stdout,"Multicase echo server ,listen on %d,fd%d,group %s\n",port,listen_fd,group_ip);

     /* 第四步:开始用等待客户端的联接 */
       echo_thread((void *)listen_fd);

      fprintf(stdout,"close UDP server\n");
     exit_handler(0);
  
    
}


客户端代码

/*
  UDP MultiCast Echo Client
   Author :Andrew Huang

 
 */


#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>

#include <stdlib.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>

static int udp_fd = -1;

void exit_handler(int no)
{
   close(udp_fd);
    exit(0);
}

void * echo_thread(void *arg)
{
    struct sockaddr_in peer_addr;
     
     socklen_t sockaddr_len = sizeof(struct sockaddr_in);
      char buffer[1024];
     int len;



   
     
    while(1)
      {
         len = recvfrom(udp_fd,buffer,len,0,(struct sockaddr *)&peer_addr,&sockaddr_len);
              if(len <= 0)
                   {
                      perror("recv");
                          break;
                   }
             fprintf(stdout,"recv echo from %s:%d,MESSAGE %s\n",inet_ntoa(peer_addr.sin_addr),ntohs(peer_addr.sin_port),buffer);
          
      }
}

/* 加入某个主播组 */
int add_multicast_group(int udp_fd,char * mgroup_ip)
{
   struct ip_mreq multi_req;


    multi_req.imr_multiaddr.s_addr = inet_addr(mgroup_ip);

    multi_req.imr_interface.s_addr = htonl(INADDR_ANY);

    if (-1 == setsockopt(udp_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&multi_req,
sizeof(multi_req)))
    {
       perror("setsockopt_multi");
       return -1;
    }


  return 0;

}

int main(int argc,char * argv[])
{
   unsigned short port = 10050;
    unsigned char ip[32] = "224.0.0.0"; //组播地址

    char buffer[1024];
    ssize_t len;


    signal(SIGTERM,exit_handler);
    signal(SIGINT,exit_handler);

    pthread_t th;

   
    struct sockaddr_in server_addr;
    
    socklen_t sockaddr_len = sizeof(struct sockaddr_in);

   if(argc > 1)
      port = (unsigned short)atoi(argv[1]);

    if(argc > 2)
       strncpy(ip,argv[2],sizeof(ip)-1);



    /* 第一步:创建UDP SOCKET*/
    udp_fd = socket(PF_INET,SOCK_DGRAM,0);
     if(udp_fd == -1)
       {
          perror("socket");
       }

   /* 第二步:可选操作bind,如果没有bind,UDP协议栈自动选一个端口 */
  #if 1
    /* 加入某一个组播组*/
     if(add_multicast_group(udp_fd,ip)!= 0)
           {
              exit(-1);
           }
   #endif
    /* 第三步:联接服务器 */
      server_addr.sin_family = AF_INET ; /* ipv4 */
      server_addr.sin_port = htons(port);
       server_addr.sin_addr.s_addr =inet_addr(ip);

    fprintf(stdout,"Remote Multicast echo server %s:%d\n",ip,port);

    
    pthread_create(&th,NULL,echo_thread,NULL);

    while(1)
      {
         if(fgets(buffer,sizeof(buffer)-1,stdin)== NULL)
             {
              perror("fgets");
             continue;
             }
          
          if(strncmp(buffer,"exit",4) == 0)
               {
                 send(udp_fd,"exit",5,0);
                    exit_handler(0);
                      break;
               }


            len = strlen(buffer)+1;

           if((len = sendto(udp_fd,buffer,len,0,(struct sockaddr *)&server_addr,sockaddr_len))<= 0)
               {
                  perror("send");
                     continue;
               }
                

             
          }
 } /* main */
    
    


阅读(1230) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~