免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 15902 | 回复: 4
打印 上一主题 下一主题

Linux socket写的UDP 广播的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-06-26 10:40 |只看该作者 |倒序浏览
正在学习Linux Socket ,用的是《Linux Socket Programming》这本书。里面有一段UDP广播的程序
如下:
/*服务器程序,用来发送广播包,模拟股市信息*/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<time.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#ifndef TRUE
#define TRUE        1
#define FALSE        0
#endif

/*mkaddr()函数把一个字符串的IP地址,转换为AF_INET,经测试mkaddr函数正确*/
extern int mkaddr(void *addr,int *addrlen,char *str_addr,char *protocol);

#define MAXQ        4

static struct{
        char *index;
        int start;
        int volit;
        int current;
        }quotes[]={
                {"DJIA",1030330,375},
                {"NASDAQ",128331,125},
                {"S&P 500",276175,125},
                {"TSE 300",689572,75},
                };

/*初始化函数*/
static void initialize(void)
{
        short x;
        time_t td;
       
        /*Seed the random number generator*/
        time(&td);
        srand((int)td);
       
        for(x = 0;x<MAXQ;++x)
        {
                quotes[x].current =quotes[x].start;
        }
}
       
/*随即的改变股票指数*/
static void gen_quote(void)
{
        short x; /*Index*/
        short v; /*Volatility of index*/
        short h; /*half of v*/
        short r; /*changed randomly*/
               
        x = rand()%MAXQ;
        v =quotes[x].volit;
        h = (v/2) - 2;
        r = rand()%v;
        if(r < h)
        {
                r = -r;
        }
        quotes[x].current += r;
               
}
       
/*F用来报错的函数 */
static void fail(const char *on_what)
{
        if(errno > 0)
        {
                fputs(strerror(errno),stderr);
                fputs(":",stderr);
        }
        fputs(on_what,stderr);
        fputc('\n',stderr);
        exit(1);
}

int main(int argc,char *argv[])
{
        short x;  /*Index of Stock index*/
        double I0; /*Initial index value*/
        double I; /*Index value */
        char bcbuf[512],*bp; /*buffer and index*/
        int z; /*status return code*/
        int s; /*socket*/
        struct sockaddr_in adr_srvr; /*AF_INET*/
        int len_srvr; /*length*/
        struct sockaddr_in adr_bc; /*AF_INET*/
        int len_bc; /*length*/
        static int so_broadcast = TRUE;
        static char *sv_addr = "127.0.0.1:*";
        static char *bc_addr = "127.255.255.255:9097";
                    
        /*从命令行得到IP地址*/
        if( argc > 2)
        {
                /*Server address*/
                sv_addr = argv[2];
        }
        if(argc>1)
        {
                /*Broadcast address*/
                bc_addr = argv[1];
        }
       
        /*用程序构造服务器地址*/
        len_srvr = sizeof(adr_srvr);
       
        z = mkaddr(&adr_srvr,&len_srvr,sv_addr,"udp");
       
        if(z == -1)
        {
                fail("Bad server address!");
        }
       
        /*创建UDP 套接字*/
        s = socket(AF_INET,SOCK_DGRAM,0);
        if(s == -1)
        {
                fail("socket()");
        }
       
        /*允许广播*/
        z = setsockopt(s,SOL_SOCKET,SO_BROADCAST,&so_broadcast,sizeof(so_broadcast));
       
       
        if(z == -1)
        {
                fail("setsockopt(SO_BROADCAST)");
        }
       
        z = bind(s,(struct sockaddr *)&adr_srvr,len_srvr);
        if(z == -1)
        {
                fail("bind()");
        }
       
        /*启动报价服务*/
        initialize();
        len_bc = sizeof(adr_bc);
       
        while(1)
        {
                gen_quote();
               
                bp = bcbuf;
                for(x=0;x<MAXQ;x++)
                {
                        I0 =quotes[x].start / 100.0;
                        I =quotes[x].current / 100.0;
                        sprintf(bp,"%-7.7s %8.2f %+.2f\n",quotes[x].index,I,I-I0);
                        bp += strlen(bp);
                }
               
               
               
                z = sendto(s,bcbuf,strlen(bcbuf),0,(struct sockaddr *)&adr_bc,len_bc);
               
                if(z == -1)
                {
                        fail("sendto()");
                }
               
                sleep(4);
        }
       
        return 0;
}

论坛徽章:
0
2 [报告]
发表于 2007-06-26 10:43 |只看该作者
/*接受广播的函数*/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<time.h>
#include<signal.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#ifndef TRUE
#define TRUE        1
#define FALSE        0
#endif

extern int mkaddr(void *addr,int *addrlen,char *str_len,char *protocol);

/*报错函数*/
void fail(const char *on_what)
{
        if(errno > 0)
        {
                fputs(strerror(errno),stderr);
                fputs(":",stderr);
        }
        fputs(on_what,stderr);
        fputc('\n',stderr);
        exit(1);
}



int main(int argc,char *argv[])
{
        int z;  /*State return code*/
        int x;
        struct sockaddr_in adr; /*AF_INET*/
        int len_inet;  /*length*/
        int s; /*socket*/
        char dgram[512]; /*receive buffer*/
        static int so_reuseaddr = TRUE;
        static char *bc_addr = "127.255.255.255:9097";
       
        /*Use the server address from the command line
         *else use the default address:
         *127.0.0.23
         */
         if(argc > 1)
         {
                 bc_addr = argv[1];
         }
         
         /*创建UDP套接字*/
         s = socket(AF_INET,SOCK_DGRAM,0);
         if(s == -1)
         {
                 fail("socket()");
         }
         
         /*建立广播地址*/
         len_inet = sizeof(adr);
         
         z = mkaddr(&adr,&len_inet,bc_addr,"udp");
         if(z == -1)
         {
                 fail("Bad broadcast address");
         }
         
       
          z = setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&so_reuseaddr,sizeof(so_reuseaddr));
          
          if(z == -1)
          {
                  fail("setsockopt(SO_REUSEADDR)");
          }
          
          /*将广播地址绑定到套接字*/
          z = bind(s,(struct sockaddr *)&adr,len_inet);
          if(z == -1)
          {
                  fail("bind()");
          }
          
          while(1)
          {
                  /*Waiting for broadcast messages*/
                  z = recvfrom(s,dgram,sizeof(dgram),0,(struct sockaddr *)&adr,&x);
          
                  if(z < 0)
                  {
                          fail("recvfrom()");
                  }
                 
                  fwrite(dgram,z,1,stdout);
                  putchar('\n');
                 
                  fflush(stdout);
                 
          }
          
          return 0;
}

论坛徽章:
0
3 [报告]
发表于 2007-06-26 10:49 |只看该作者
编译正确,但是执行以下命令:
./stksrv 127.255.255.255:9097 &
时出现如下错误:
[root@localhost c]# ./stksrv 127.255.255.255:9097 &
[1] 2763
[root@localhost c]# Invalid argument:sendto()

[1]+  Exit 1                  ./stksrv 127.255.255.255:9097


那位高手看看是什么原因???????

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2007-06-26 14:18 |只看该作者
man sendto

BTW:为嘛要告诉我们 ./stksrv 127.255.255.255:9097 & 的结果而不是 ./stksrv 127.255.255.255:9097  的结果?

论坛徽章:
0
5 [报告]
发表于 2007-06-26 15:19 |只看该作者
./stksrv的结果如下:
[root@localhost c]# ./stksrv 127.255.255.255:9097
Invalid argument:sendto()
[root@localhost c]#
不明白为什么sendto 的参数出问题了。
查看man 手册还是看不出自己的错误,恳请指正。谢谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP