Linux下使用ioctl獲取本地介面IP

2021-07-11 12:16:04 字數 3323 閱讀 7709

最近在ubuntu上寫ftp伺服器時封裝了getlocalip來獲取本機ip,函式內部使用gethostname()獲取主機名,使用gethostbyname()來獲取主機ip列表,但是用該函式獲取的ip繫結socket去使用connect方法時會失敗,errno**為22,invalid argument,列印輸出獲取的ip,發現獲取的ip為127.0.1.1。經查詢文件,gethostbyname()會去解析/etc/hosts檔案來獲取ip,檢視該檔案發現裡面只有兩行1.127.0.0.1 localhost  2.127.1.1.1 主機名 ,所以根據主機名來獲取ip會返回127.0.1.1,與用ifconfig檢視到的ip不相等。搜尋了一下,網上有其他人遇到了此問題,可以通過解析/etc/sysconfig/network-scripts目錄下的ifcfg-eth0等網絡卡配置檔案來讀取真實ip,但是ubuntu沒有該目錄,經過查閱資料,可以使用ioctl讀取網絡卡資訊獲取ip,終端下輸入 man netdevice

主要有兩個結構體,struct ifconf 和 struct ifreq,具體含義由ioctl第二個引數決定,前者儲存所有網絡卡裝置得到資訊,後者儲存網絡卡介面名稱及對應的ip位址等資訊,ioctl函式原型如下:

int ioctl(int d, int request, ...);

類別

request

說明

資料型別套 接

口siocatmark

siocspgrp

siocgpgrp

是否位於帶外標記

設定套介面的程序id 或程序組id

獲取套介面的程序id 或程序組id

int

int

int 文

件fionbio

fioasync

fionread

fiosetown

fiogetown

設定/ 清除非阻塞i/o 標誌

設定/ 清除訊號驅動非同步i/o 標誌

獲取接收快取區中的位元組數

設定檔案的程序id 或程序組id

獲取檔案的程序id 或程序組id

int

int

int

int

int 接

口siocgifconf

siocsifaddr

siocgifaddr

siocsifflags

siocgifflags

siocsifdstaddr

siocgifdstaddr

siocgifbrdaddr

siocsifbrdaddr

siocgifnetmask

siocsifnetmask

siocgifmetric

siocsifmetric

siocgifmtu

sioc***

獲取所有介面的清單

設定介面位址

獲取介面位址

設定介面標誌

獲取介面標誌

設定點到點位址

獲取點到點位址

獲取廣播位址

設定廣播位址

獲取子網掩碼

設定子網掩碼

獲取介面的測度

設定介面的測度

獲取介面mtu

(還有很多取決於系統的實現)

struct ifconf

struct ifreq

struct ifreq

struct ifreq

struct ifreq

struct ifreq

struct ifreq

struct ifreq

struct ifreq

struct ifreq

struct ifreq

struct ifreq

struct ifreq

struct ifreq

arp

siocsarp

siocgarp

siocdarp

建立/ 修改arp 表項

獲取arp 表項

刪除arp 表項

struct arpreq

struct arpreq

struct arpreq路 由

siocaddrt

siocdelrt

siocrtmsg

增加路徑

刪除路徑

獲取路由表

struct rtentry

struct rtentry

struct rtentry

流 i_***

具體**如下:

1.直接獲取指定網絡卡ip

#include#include#include#include#include#include#includeint main()

strcpy(ifr.ifr_name,"wlan0");

if(ioctl(sockfd, siocgifaddr, &ifr) < 0)//直接獲取ip位址

memcpy(&sin, &ifr.ifr_dstaddr, sizeof(sin));

printf("ip is %s \n",inet_ntoa(sin.sin_addr));

return 0;

}

直接獲取無線網絡卡ip,輸出結果如下:

2.獲取所有網路裝置並輸出ip:

#include #include #include #include #include #include #include int main()

//獲取所有介面資訊

ioctl(sockfd, siocgifconf, &ifconf);

//逐個獲取ip位址

ifreq = (struct ifreq*)buf;

for(i = (ifconf.ifc_len/sizeof(struct ifreq)); i>0; i--)

return 0;

}

使用ifconfig命令檢視網路介面資訊並對比輸出結果如下:

可以看到,使用ioctl獲取本地ip的方法比gethostbyname()更加可靠,實際使用時可以根據需要獲取指定網絡卡的ip資訊。

LInux下的網路ioctl使用

最近需要修改linux下的網路引數,遂將linux下用於控制網路引數的 ioctl常用函式記錄一下,使用的時候注意使包裹對應的標頭檔案,其中sockios.件包含所有的操作命令字,int main int argc,char ar int error struct ethtool link sett...

linux系統ioctl使用示例

linux系統ioctl使用示例 these were writed and collected by kf701,you can use and modify them but no warranty.contact with me kf 701 21cn.com 程式1 檢測介面的 inet a...

linux系統ioctl使用示例

程式4 include include include include include include include include include include define base value 257 int main int argc,char argv int mixer fd 0 c...