Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1683091
  • 博文数量: 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 00:40:45

Andrew Huang 转载请注明作者及联络方式

这个程序的前身是

一.关于UDP广播的实现
---------------------------------------------------------
关于setsockopt


二.UDP广播代码
---------------------------------------------------------------------

广播客户端 udp_echo_cli.c

  

/*
  UDP Broadcast Echo Client
 
   Author :Andrew Huang

 */


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


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


int main(int argc ,char * argv[])
{
  unsigned short port = 9002;
  int sock;


    char ipaddr[32] = "10.1.0.255";
    char buf[32] = "hello server";
    struct sockaddr_in serv_addr;
    int len;
     socklen_t addr_len;

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

    if(argc >2)
     {
          memset(ipaddr,0,sizeof(ipaddr));
         strncpy(ipaddr,argv[2],sizeof(ipaddr)-1);
     }

    if(argc > 3)
       {
            memset(buf,0,sizeof(buf));
         strncpy(buf,argv[3],sizeof(buf)-1);
        }


 printf("connect server %s:%d,buf %s\n",ipaddr,port,buf);

  //第一步:创建一个IPV4,UDP,可以运行所有协议的SOCKET

   sock = socket(PF_INET,SOCK_DGRAM,0);
   if(sock == -1)
      {
          perror("socket");
          return -1;
      }

   //打开广播选项

       {
           int val = 1;
                if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *) &val, sizeof (val)) == -1)
       {
          perror("setsockopt");
        }
       }

   fprintf(stdout,"send broadcast on %s:%d\n",ipaddr,port);

     
        //第二步:对于客户端,port可用任意一个编号,如果不使用bind,协议栈会自动分配没用的端口0

    // 省略bind ....

    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port);
    serv_addr.sin_addr.s_addr = inet_addr(ipaddr);


     sendto(sock,buf,strlen(buf)+1,0,(struct sockaddr *)&serv_addr,sizeof(serv_addr));


{//可以从socket取到自己所绑定的端口和地址

       memset(&serv_addr ,0 ,sizeof(serv_addr));
                 addr_len = sizeof(serv_addr);
             getsockname(sock,(struct sockaddr *)&serv_addr,&addr_len);
           
           fprintf(stdout,"local addr %s ,port %d\n",inet_ntoa(serv_addr.sin_addr),ntohs(serv_addr.sin_port));
   }

     len = recvfrom(sock,buf,sizeof(buf),0,NULL,NULL);
      if(len >0)
       {
         buf[len] = 0;
        fprintf(stdout,"SERVER:%s\n",buf);

       }

      //关闭socket

     close(sock);
     
    
}


服务器代码同它的前身一模一样,udp_echo_svr.c

/*
  UDP Echo Server
  
  Author :Andrew Huang
 */


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


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





int main(int argc ,char * argv[])
{
  unsigned short port = 9000;
  int sock_fd;


 struct sockaddr_in addr; //ipv4的地址结构

   struct sockaddr_in client_addr ;
   socklen_t addr_len;

    char buf[1024];
   int len ;

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

  //第一步:创建一个IPV4,UDP,可以运行所有协议的SOCKET

  sock_fd = socket(PF_INET,SOCK_DGRAM,0);
  if(sock_fd == -1)
   {
        perror("socket");
         return -1;
   }


   //第二步:用bind来指定端口

   memset(&addr,0,sizeof(addr));
    addr.sin_port = htons(port); //转成网络序的端口

   addr.sin_family = AF_INET; //ipv4的地址类型

   //addr.sin_addr.s_addr = inet_addr("0.0.0.0"); //bind 的sin_addr表示在哪一个网卡上有效,

   //绑定在0.0.0.0上表示这个SOCKET在所有网卡侦听

   addr.sin_addr.s_addr = INADDR_ANY; //INADDR_ANY = 0 = inet_addr("0.0.0.0")


    if(bind(sock_fd,(const struct sockaddr *)&addr,sizeof(addr)) == -1)
       {
          perror("bind");
          close(sock_fd);
          return -2;
       }


    fprintf(stdout,"UDP Echo Server listen on %d\n",port);

   while(1)
    {
         memset(&client_addr,0,sizeof(client_addr));
         client_addr.sin_family = AF_INET;
         addr_len = sizeof(client_addr);

         len = recvfrom(sock_fd,buf,sizeof(buf),0,(struct sockaddr *)&client_addr,&addr_len);

         if(len <=0)
               continue;
             
           buf[len] = 0;

           // 以下这种写法表示不关心这个包是从哪里发来,只是接收内容

          //len = recvfrom(sock_fd,buf,sizeof(buf),0,NULL,NULL);


          fprintf(stdout,"client addr %s ,port %d,buf %s\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port),buf);

           
          sendto(sock_fd,buf,len,0,(struct sockaddr *)&client_addr,addr_len);

      
    }

    close(sock_fd);
}


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