利用广播获取CB的IP地址
本帖最后由 soloforce 于 2014-10-6 19:30 编辑对于无显示器CB Linux系统,且IP地址为动态获取方式时,获取CB系统的IP地址可能是一个令人头疼的问题;然而利用局域网广播方法,则可以让与CB系统位于同一个局域网的其他机器得到CB系统的IP地址,仅仅需要Linux下socket编程的一些知识以及若干行代码。此外,为了适合各种类型的局域网,采用255.255.255.255的广播地址;当然,广播包不会被路由器转发。
===== CB系统代码 =====
/* filename: brdip.c
*
* IP broadcast via UDP
* by soloforce, 2014
*/
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include <arpa/inet.h>
#include<netdb.h>
#define PORT 7777
#define MAXDATASIZE 256
int main(int argc,char *argv[])
{
int socket_fd;
struct sockaddr_in my_addr,user_addr;
char buf;
int so_broadcast=1;
socklen_t size;
char my_ip;
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(PORT);
my_addr.sin_addr.s_addr=inet_addr("255.255.255.255");
bzero(&(my_addr.sin_zero),8);
user_addr.sin_family=AF_INET;
user_addr.sin_port=htons(PORT);
user_addr.sin_addr.s_addr=htonl(INADDR_ANY);
bzero(&(user_addr.sin_zero),8);
if((socket_fd=(socket(AF_INET,SOCK_DGRAM,0)))==-1) {
perror("socket");
exit(1);
}
setsockopt(socket_fd,SOL_SOCKET,SO_BROADCAST,&so_broadcast,sizeof(so_broadcast));
if((bind(socket_fd,(struct sockaddr *)&user_addr,
sizeof(struct sockaddr)))==-1) {
perror("bind");
exit(1);
}
// broadcast a message
strcpy(buf,"Cubieboard on line!");
sendto(socket_fd,buf,strlen(buf),0,(struct sockaddr *)&my_addr,sizeof(my_addr));
// receive the message broadcast just now, to get user_addr which contains the IP info.
size=sizeof(user_addr);
recvfrom(socket_fd,buf,MAXDATASIZE,0,(struct sockaddr *)&user_addr,&size);
// extract the IP info
bzero(buf, sizeof(buf));
sprintf(buf, "Cubieboard IP: %s\n",inet_ntoa(user_addr.sin_addr));
// keep broadcast the IP info in 3 secs.
while(1) {
sendto(socket_fd,buf,strlen(buf),0,(struct sockaddr *)&my_addr,sizeof(my_addr));
sleep(3);
}
return 0;
}
===== 客户机(Linux系统)代码 =====
/* filename: udprecv.c
*
* receive IP info via UDP
* by soloforce, 2014
*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 7777
#define MAXDATASIZE 256
int main(int argc, char**argv)
{
int sockfd,n;
struct sockaddr_in servaddr,cliaddr;
socklen_t size;
char buf;
sockfd=socket(AF_INET,SOCK_DGRAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(PORT);
bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
while(1){
size = sizeof(cliaddr);
bzero(buf, sizeof(buf));
n = recvfrom(sockfd,buf,1000,0,(struct sockaddr *)&cliaddr,&size);
buf = 0;
printf("%s",buf);
}
}
===== 编译与执行 =====
分别在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
...
本帖最后由 jerryli 于 2014-10-5 15:29 编辑
其实真的不要用那么麻烦。
我是这样做的,一般CT或者CB都是放在局域网用的,内网的出口一般就是路由器。
所以你只需要把CB接入网络,然后登录到路由器上看DHCP列表,路由器在分配IP后能看到已经连接主机,你找对应的host名称就行了(如果你是用默认的host没有修改过,一般一眼都能看出来是哪台)。
------------------
找到主机的IP后,下一步你就需要在路由器的DHCP上配置绑定MAC地址固定IP,这样每次你的这个设备联入这个网络的时候,IP地址就不会改变了。
jerryli 发表于 2014-10-5 15:24 static/image/common/back.gif
其实真的不要用那么麻烦。
我是这样做的,一般CT或者CB都是放在局域网用的,内网的出口一般就是路由器。
你说的对。直接到路由器查阅IP,或者根据MAC绑定IP,或者直接设置成静态IP,或者搬来一个显示器,或者用TTL线看……即使已经有100种办法了,多一种办法仍旧是好事 :) 估计折腾CB的就两类人,一类是不会丁点编程,不懂linux的人;一类是程序员。
楼上两位的方法,分别适合这两类人。
如果是新手的话,补充下LZ的问题:LZ的这个小程序,还要想办法把这个小程序添加到 linux的开机启动项,具体百度和google都有很多方法
我这里也有另外一份代码分享下,效果是一样的:
https://github.com/boyisgood86/learning/blob/master/getlocalip.c 醉月 发表于 2014-10-5 19:11 static/image/common/back.gif
估计折腾CB的就两类人,一类是不会丁点编程,不懂linux的人;一类是程序员。
楼上两位的方法,分别适合这两 ...
补充的好! 抛砖引出玉了,hoho :) 又多了一种方法!一般我只直接查阅DHCP列表的。呵呵!这玩意真是折腾死人啊,其乐无穷啊! 其实这种方法的初衷是用在一个自定制的CB Linux 上, 无显示器, 无TTL,IP是动态获取的,那么这时就可以通过广播方式告知位于同一子网的其他客户机; 如果对安全有要求的用户,可以考虑把报文经过OPENSSL加密后发送,客户端预先装好了证书,即可保证信息安全。 谢谢soloforce的分享,有用!自动获取地址后,准备用于自动更新box里面的内容。
另外之前只想到配置固定ip,居然没想到绑定mac,也谢谢jerryli。 我是安裝 sudo apt-get install samba , 用 PC Ping CB2 的 Hostname 就可以了 !!
但是 CB2 互相 Ping 則無法解譯名稱 !!
不知道用這方法好不好 ? 感谢各位的讨论,受教了。
页:
[1]