CubieBoard中文论坛

 找回密码
 立即注册
搜索
热搜: unable
查看: 14566|回复: 9

利用广播获取CB的IP地址

[复制链接]
发表于 2014-10-5 08:53:43 | 显示全部楼层 |阅读模式
本帖最后由 soloforce 于 2014-10-6 19:30 编辑

对于无显示器CB Linux系统,且IP地址为动态获取方式时,获取CB系统的IP地址可能是一个令人头疼的问题;然而利用局域网广播方法,则可以让与CB系统位于同一个局域网的其他机器得到CB系统的IP地址,仅仅需要Linux下socket编程的一些知识以及若干行代码。此外,为了适合各种类型的局域网,采用255.255.255.255的广播地址;当然,广播包不会被路由器转发。
===== CB系统代码 =====


  1. /* filename: brdip.c
  2. *
  3. * IP broadcast via UDP
  4. * by soloforce, 2014
  5. */

  6. #include<stdio.h>
  7. #include<stdlib.h>
  8. #include<errno.h>
  9. #include<string.h>
  10. #include<sys/types.h>
  11. #include<netinet/in.h>
  12. #include<sys/socket.h>
  13. #include<sys/wait.h>
  14. #include<sys/stat.h>
  15. #include<fcntl.h>
  16. #include<unistd.h>
  17. #include <arpa/inet.h>
  18. #include<netdb.h>

  19. #define PORT 7777
  20. #define MAXDATASIZE 256

  21. int main(int argc,char *argv[])
  22. {
  23.     int socket_fd;
  24.     struct sockaddr_in my_addr,user_addr;
  25.     char buf[MAXDATASIZE];
  26.     int so_broadcast=1;
  27.     socklen_t size;
  28.     char my_ip[12];
  29.     my_addr.sin_family=AF_INET;
  30.     my_addr.sin_port=htons(PORT);
  31.     my_addr.sin_addr.s_addr=inet_addr("255.255.255.255");
  32.     bzero(&(my_addr.sin_zero),8);

  33.     user_addr.sin_family=AF_INET;
  34.     user_addr.sin_port=htons(PORT);
  35.     user_addr.sin_addr.s_addr=htonl(INADDR_ANY);
  36.     bzero(&(user_addr.sin_zero),8);
  37.     if((socket_fd=(socket(AF_INET,SOCK_DGRAM,0)))==-1) {
  38.         perror("socket");
  39.         exit(1);
  40.     }
  41.     setsockopt(socket_fd,SOL_SOCKET,SO_BROADCAST,&so_broadcast,sizeof(so_broadcast));
  42.     if((bind(socket_fd,(struct sockaddr *)&user_addr,
  43.                         sizeof(struct sockaddr)))==-1) {
  44.         perror("bind");
  45.         exit(1);
  46.     }

  47.     // broadcast a message
  48.     strcpy(buf,"Cubieboard on line!");
  49.     sendto(socket_fd,buf,strlen(buf),0,(struct sockaddr *)&my_addr,sizeof(my_addr));

  50.     // receive the message broadcast just now, to get user_addr which contains the IP info.
  51.     size=sizeof(user_addr);
  52.     recvfrom(socket_fd,buf,MAXDATASIZE,0,(struct sockaddr *)&user_addr,&size);

  53.     // extract the IP info
  54.     bzero(buf, sizeof(buf));
  55.     sprintf(buf, "Cubieboard IP: %s\n",inet_ntoa(user_addr.sin_addr));

  56.     // keep broadcast the IP info in 3 secs.
  57.     while(1) {
  58.         sendto(socket_fd,buf,strlen(buf),0,(struct sockaddr *)&my_addr,sizeof(my_addr));
  59.         sleep(3);
  60.     }
  61.     return 0;
  62. }
复制代码
===== 客户机(Linux系统)代码 =====

  1. /* filename: udprecv.c
  2. *
  3. * receive IP info via UDP
  4. * by soloforce, 2014
  5. */

  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>

  11. #define PORT 7777
  12. #define MAXDATASIZE 256

  13. int main(int argc, char**argv)
  14. {
  15.    int sockfd,n;
  16.    struct sockaddr_in servaddr,cliaddr;
  17.    socklen_t size;
  18.    char buf[MAXDATASIZE];

  19.    sockfd=socket(AF_INET,SOCK_DGRAM,0);
  20.    bzero(&servaddr,sizeof(servaddr));
  21.    servaddr.sin_family = AF_INET;
  22.    servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
  23.    servaddr.sin_port=htons(PORT);
  24.    bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

  25.    while(1){
  26.       size = sizeof(cliaddr);
  27.       bzero(buf, sizeof(buf));
  28.       n = recvfrom(sockfd,buf,1000,0,(struct sockaddr *)&cliaddr,&size);
  29.       buf[n] = 0;
  30.       printf("%s",buf);
  31.    }
  32. }

复制代码
===== 编译与执行 =====
分别在CB系统和客户系统中编译程序
  CB $ gcc brdip.c -o brdip
  GUEST $ gcc udprecv.c -o udprecv
分别执行之
  CB $ ./brdip
  GUEST $ ./udprecv
在客户系统中可以看到如下显示
Cubieboard IP: 192.168.1.124

Cubieboard IP: 192.168.1.124

Cubieboard IP: 192.168.1.124

Cubieboard IP: 192.168.1.124

Cubieboard IP: 192.168.1.124

Cubieboard IP: 192.168.1.124

Cubieboard IP: 192.168.1.124

Cubieboard IP: 192.168.1.124

Cubieboard IP: 192.168.1.124

Cubieboard IP: 192.168.1.124
...


评分

参与人数 1威望 +5 金钱 +5 贡献 +5 收起 理由
cubieplayer + 5 + 5 + 5 在某些场合下还是很有用的,谢谢分享.

查看全部评分

回复

使用道具 举报

发表于 2014-10-5 15:24:34 | 显示全部楼层
本帖最后由 jerryli 于 2014-10-5 15:29 编辑

其实真的不要用那么麻烦。

我是这样做的,一般CT或者CB都是放在局域网用的,内网的出口一般就是路由器。

所以你只需要把CB接入网络,然后登录到路由器上看DHCP列表,路由器在分配IP后能看到已经连接主机,你找对应的host名称就行了(如果你是用默认的host没有修改过,一般一眼都能看出来是哪台)。

------------------
找到主机的IP后,下一步你就需要在路由器的DHCP上配置绑定MAC地址固定IP,这样每次你的这个设备联入这个网络的时候,IP地址就不会改变了。

回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-10-5 17:10:35 | 显示全部楼层
jerryli 发表于 2014-10-5 15:24
其实真的不要用那么麻烦。

我是这样做的,一般CT或者CB都是放在局域网用的,内网的出口一般就是路由器。

你说的对。直接到路由器查阅IP,或者根据MAC绑定IP,或者直接设置成静态IP,或者搬来一个显示器,或者用TTL线看……即使已经有100种办法了,多一种办法仍旧是好事
回复 支持 反对

使用道具 举报

发表于 2014-10-5 19:11:51 | 显示全部楼层
估计折腾CB的就两类人,一类是不会丁点编程,不懂linux的人;一类是程序员。
楼上两位的方法,分别适合这两类人。

如果是新手的话,补充下LZ的问题:LZ的这个小程序,还要想办法把这个小程序添加到 linux的开机启动项,具体百度和google都有很多方法

我这里也有另外一份代码分享下,效果是一样的:
https://github.com/boyisgood86/learning/blob/master/getlocalip.c
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-10-5 21:44:21 | 显示全部楼层
醉月 发表于 2014-10-5 19:11
估计折腾CB的就两类人,一类是不会丁点编程,不懂linux的人;一类是程序员。
楼上两位的方法,分别适合这两 ...

补充的好! 抛砖引出玉了,hoho
回复 支持 反对

使用道具 举报

发表于 2014-10-6 10:47:38 | 显示全部楼层
又多了一种方法!一般我只直接查阅DHCP列表的。呵呵!这玩意真是折腾死人啊,其乐无穷啊!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-10-6 19:34:33 | 显示全部楼层
其实这种方法的初衷是用在一个自定制的CB Linux 上, 无显示器, 无TTL,IP是动态获取的,那么这时就可以通过广播方式告知位于同一子网的其他客户机; 如果对安全有要求的用户,可以考虑把报文经过OPENSSL加密后发送,客户端预先装好了证书,即可保证信息安全。
回复 支持 反对

使用道具 举报

发表于 2014-10-8 10:39:25 | 显示全部楼层
谢谢soloforce的分享,有用!自动获取地址后,准备用于自动更新box里面的内容。
另外之前只想到配置固定ip,居然没想到绑定mac,也谢谢jerryli。
回复 支持 反对

使用道具 举报

发表于 2014-11-10 17:52:37 | 显示全部楼层
我是安裝 sudo apt-get install samba , 用 PC Ping CB2 的 Hostname 就可以了 !!

但是 CB2 互相 Ping 則無法解譯名稱 !!

不知道用這方法好不好 ?
回复 支持 反对

使用道具 举报

发表于 2015-10-23 20:03:32 | 显示全部楼层
感谢各位的讨论,受教了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|粤ICP备13051116号|cubie.cc---深刻的嵌入式技术讨论社区

GMT+8, 2024-3-28 22:35 , Processed in 0.028845 second(s), 16 queries .

Powered by Discuz! X3.4

© 2001-2012 Comsenz Inc. | Style by Coxxs

返回顶部