bzero函数_函数模块 | UDP自动获取本地广播地址
讓技術(shù)·去旅行
點(diǎn)擊上方藍(lán)字可以關(guān)注我們哦
本文以函數(shù)形式做筆記,因?yàn)楹瘮?shù)模塊式編程,可以大大提升代碼的可讀性。
首先來了解ifreq?這個(gè)結(jié)構(gòu)體
1、結(jié)構(gòu)定義
struct?ifconf?
{? ? ?int?ifc_len; ????union?2、用法說明
? ? ? ? ifreq結(jié)構(gòu)定義在/usr/include/net/if.h,用來配置ip地址,激活接口,配置MTU等接口信息的。其中包含了一個(gè)接口的名字和具體內(nèi)容——(是個(gè)共用體,有可能是IP地址,廣播地址,子網(wǎng)掩碼,MAC號(hào),MTU或其他內(nèi)容)。ifreq包含在ifconf結(jié)構(gòu)中。而 ifconf結(jié)構(gòu)通常是用來保存所有接口的信息的。
然后淺談一下ioctl函數(shù)
ioctl是設(shè)備驅(qū)動(dòng)程序中對設(shè)備的I/O通道進(jìn)行管理的函數(shù)。所謂對I/O通道進(jìn)行管理,就是對設(shè)備的一些特性進(jìn)行控制,例如串口的傳輸波特率、馬達(dá)的轉(zhuǎn)速等等。具體操作,自行百度深入
函數(shù)原型為:
本函數(shù)影響由fd參數(shù)引用的一個(gè)打開的文件。
#include
int?ioctl( int?fd, int?request, .../* void *arg */?);
返回0:成功?返回-1:出錯(cuò)
第三個(gè)參數(shù)總是一個(gè)指針,但指針的類型依賴于request參數(shù)。
本文函數(shù)調(diào)用如下
//直接獲取指定網(wǎng)卡的地址信息到ifr結(jié)構(gòu)體里面
ioctl(skt_fd, SIOCGIFADDR, &ifr);
接下分析如何獲取本地廣播地址
前言:
在main函數(shù)調(diào)用這個(gè)函數(shù)是這樣子的
函數(shù)名字:get_netcard_broadcase_addr
函數(shù)功能:根據(jù)網(wǎng)卡名字獲取IP地址是多少
get_netcard_broadcase_addr(udp_fd, "ens38", broadcase_addr,
????????????????sizeof(broadcase_addr));參數(shù)分析:
udp_fd:?socket文件描述符
ens38 :網(wǎng)卡名字
broadcast_addr:?用來存放網(wǎng)絡(luò)通信信息?,需要提前定義struct sockaddr_in ?broadcast_addr
???????????? struct sockaddr_in 這個(gè)結(jié)構(gòu)體用來處理網(wǎng)絡(luò)通信的地址,比如說把類型、ip地址、端口填充sockaddr_in結(jié)構(gòu)體? ? ? ? ? ??
sizeof(broadcase_addr):結(jié)構(gòu)體的大小
具體實(shí)現(xiàn),請左右滑動(dòng)閱讀代碼,注釋步步到位
int?get_netcard_broadcase_addr(int?skt_fd, char?*netcard_name, char?*ip_addr, int?ip_len){
??int?retval;
??struct?ifreq?ifr;
??struct?sockaddr_in?get_addr, cache_addr;
??unsigned?int?addr_numb;
??bzero(&ifr, sizeof(ifr));//內(nèi)存清空
????
??strcpy(ifr.ifr_name, netcard_name);//將網(wǎng)卡名字放入到ifr.ifr_name的內(nèi)存當(dāng)中,指定好網(wǎng)卡的名字
??retval = ioctl(skt_fd, SIOCGIFADDR, &ifr);//直接獲取指定網(wǎng)卡的地址信息到ifr結(jié)構(gòu)體里面
??if(retval != 0)
??{
????perror("獲取指定網(wǎng)卡IP地址失敗");
????return?-1;
??}
??memcpy(&get_addr, &(ifr.ifr_addr), sizeof(get_addr));//將地址信息拷貝到get_addr結(jié)構(gòu)體里面拿來分析
??addr_numb = ntohl(get_addr.sin_addr.s_addr);//將網(wǎng)絡(luò)字節(jié)數(shù)的二進(jìn)制IP地址轉(zhuǎn)化為本地字節(jié)序的二進(jìn)制IP地址,方便我們下面做IP地址類型的判斷
??printf("本機(jī)ip地址:%s\n", inet_ntoa(get_addr.sin_addr));//將獲取到的網(wǎng)卡IP地址打印出來
??if((addr_numb & 0xe0000000) <= 0x60000000)//保留32位IP地址的前三位數(shù)據(jù),并且判斷,A類地址由于是0開頭,所以保留前面3位的最大值是011和面都是0,十六進(jìn)制數(shù)就是0x60000000
??{
??????cache_addr.sin_addr.s_addr = htonl(addr_numb|0x00ffffff);//如果他是A類地址,他的網(wǎng)絡(luò)地址則是前8位二進(jìn)制,剩下的24位都是主機(jī)地址,全部置1便是廣播地址(255就是全部都是1),并且轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)序存放進(jìn)去變量當(dāng)中
??????printf("這個(gè)是A類地址,廣播地址為%s\n", inet_ntoa(cache_addr.sin_addr));//將廣播地址打印出來
??}
??else?if((addr_numb & 0xe0000000) <= 0xa0000000)//同理,B類地址10開頭,保留3位則是101是最大值,所以十六進(jìn)制是0xa0000000
??{
??????cache_addr.sin_addr.s_addr = htonl(addr_numb|0x0000ffff);
??????printf("這個(gè)是B類地址,廣播地址為%s\n", inet_ntoa(cache_addr.sin_addr));
??}
??else?if((addr_numb & 0xe0000000) <= 0xc0000000)//同理,C類地址110開頭,保留3位則是110是最大值,所以十六進(jìn)制是0xc0000000
??{
??????cache_addr.sin_addr.s_addr = htonl(addr_numb|0x000000ff);
??????printf("這個(gè)是C類地址,廣播地址為%s\n", inet_ntoa(cache_addr.sin_addr));
??}
??else
????printf("這個(gè)是D類地址(組播地址)");
??strncpy(ip_addr, inet_ntoa(cache_addr.sin_addr), ip_len);
??return?0;
}最后驗(yàn)證這個(gè)函數(shù),如下圖所示:
該函數(shù)運(yùn)用到下面題目中
????????通過UDP,當(dāng)A運(yùn)行的時(shí)候其他同一個(gè)網(wǎng)段的B程序可以收到A上線的通知,并且都跟A程序說一句“”你好,大佬“”;
????????如果需要此題目程序代碼,后臺(tái)回復(fù)【UDP01】獲取
記錄點(diǎn)點(diǎn)滴滴的筆記歡迎關(guān)注,共同學(xué)習(xí)小浩筆記
總結(jié)
以上是生活随笔為你收集整理的bzero函数_函数模块 | UDP自动获取本地广播地址的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 双流兔头多少钱一个?
- 下一篇: python实现冒泡排序完整算法_Pyt