有沒有辦法在Linux上以編程方式使用C++來檢測本地計算機上的IP地址更改?如何在Linux中以編程方式檢測IP地址更改?
回答
在C,以獲得當前IP使用:
int s;
struct ifreq ifr = {};
s = socket(PF_INET, SOCK_DGRAM, 0);
strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFADDR, &ifr) >= 0)
printf("%s\n",
inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
替換 「eth0的」 與你在尋找的接口。您現在需要做的就是輪詢變更。
這正是「ifconfig」如何獲取接口的當前IP地址。要找出存在哪些接口名稱,它實際上會打開並解析「/ proc/net/dev」。 儘管知識產權發生變化,應該有辦法從內核獲取事件。我的猜測是使用uevents。 – nly 2009-02-24 11:20:56
一種方法是編寫一個cron作業,其中包含對庫函數的gethost系列調用。如果使用gethostbyname(),則可以比較h_addr_list的返回值。請參閱man gethostbyname。
如果你想在你的程序中做到這一點,產生一個pthread,做同樣的事情,然後睡一段任意時間。
這並不容易。每個Linux發行版使用不同的地方來存儲IP地址等(如果考慮其他UNIX變體,則會有更多的變化)。您可以使用,例如,/sbin/ifconfig
獲得接口的IP地址,但你甚至不能肯定,如果你在這個地方找到它,或者根本等
此外,由於你有那個可執行文件,你必須建立一個線程來調用它來獲得給定週期(比如說5秒)的數據,然後解釋輸出。例如,如果您有橋樑等,這可能會有所不同。也就是說,這並不容易。
我想到的一個解決方案是,如果您有機會使用GNOME或其他廣泛分佈的KDE,則可以依賴它們提供的消息/信息。例如,當設備發生變化時,NetworkManager
向DBUS standard bus輸出一個信號。你必須爲這些信號實現一個監聽器。信息here(現在不工作,所以這裏是cache)。請注意添加新接口時或當其中一個接口更改IP地址時的不同消息。這是我現在能想到的最好的方式。
如果您的用戶使用NetworkManager,則可以通過D-Bus輪詢NetworkManager.Connection.Active和NetworkManager.IP4Config,以獲得更多的確定此信息的交叉分配方式。
如果iproute2是安裝,您使用的是2.6內核,在本地接口狀態和地址到stdout
/sbin/ip monitor
將輸出的變化。你的程序可以閱讀這個。
您也可以使用與iproute2工具相同的低級別機制(我認爲它是netlink套接字)。
從的rtnetlink的手冊頁:
說明
RTNETLINK允許內核的路由表來讀取和修改。它在內核中用於在各種子系統之間進行通信,儘管這裏沒有記錄這種用法,並且用於與用戶空間程序的通信。網絡路由,IP地址,鏈路參數,鄰居設置,排隊規則,流量類別和分組分類都可以通過NETLINK_ROUTE套接字來控制。它基於netlink消息,請參閱netlink(7)以獲取更多信息。
ste的建議是使用ioctl SIOCGIFADDR在技術上是正確的,但不幸的是,對於現代Linux系統來說,單個接口可以有多個地址而不使用子接口(如eth0:1) -obsolete ifconfig。
最好的辦法是使用getifaddrs(3),這是由glibc的2.3存在:http://www.kernel.org/doc/man-pages/online/pages/man3/getifaddrs.3.html
可惜這有點低效(你找回所有接口上的所有地址的鏈接列表,將不得不遍歷找到你感興趣的人),但是在大多數情況下,你可能不會每分鐘檢查一次以上,這使得開銷可以忍受。
在這裏你去..這沒有投票。
只監聽RTM_NEWADDR但它應該是很容易改變,以支持RTM_DELADDR如果你需要
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/if.h>
int
main()
{
struct sockaddr_nl addr;
int sock, len;
char buffer[4096];
struct nlmsghdr *nlh;
if ((sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) {
perror("couldn't open NETLINK_ROUTE socket");
return 1;
}
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
addr.nl_groups = RTMGRP_IPV4_IFADDR;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
perror("couldn't bind");
return 1;
}
nlh = (struct nlmsghdr *)buffer;
while ((len = recv(sock, nlh, 4096, 0)) > 0) {
while ((NLMSG_OK(nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE)) {
if (nlh->nlmsg_type == RTM_NEWADDR) {
struct ifaddrmsg *ifa = (struct ifaddrmsg *) NLMSG_DATA(nlh);
struct rtattr *rth = IFA_RTA(ifa);
int rtl = IFA_PAYLOAD(nlh);
while (rtl && RTA_OK(rth, rtl)) {
if (rth->rta_type == IFA_LOCAL) {
uint32_t ipaddr = htonl(*((uint32_t *)RTA_DATA(rth)));
char name[IFNAMSIZ];
if_indextoname(ifa->ifa_index, name);
printf("%s is now %d.%d.%d.%d\n",
name,
(ipaddr >> 24) & 0xff,
(ipaddr >> 16) & 0xff,
(ipaddr >> 8) & 0xff,
ipaddr & 0xff);
}
rth = RTA_NEXT(rth, rtl);
}
}
nlh = NLMSG_NEXT(nlh, len);
}
}
return 0;
}
- 1. 如何檢測IP地址更改?
- 2. 如何在C或C++中以編程方式檢測OSX上的IP地址更改
- 3. 以編程方式更改Windows CE機器IP地址?
- 4. 以編程方式更改DSL連接的IP地址
- 5. 檢測Linux中IP地址的變化
- 6. 以編程方式檢索infiniband設備的IP地址
- 7. 如何檢測Android中的Wi-Fi IP地址更改
- 8. 如何以編程方式獲取Lantronix XPort IP地址
- 9. 如何以編程方式獲取Window phone 7的IP地址
- 10. 如何在C++中更改IP地址?
- 11. 如何以編程方式獲取Linux上堆的地址
- 12. 更改程序IP地址
- 13. 以編程方式更改Android付款中的帳單地址?
- 14. 如何在客戶端網站中以編程方式更改端點地址?
- 15. 如何以編程方式在VB中創建虛擬IP地址?
- 16. 以編程方式在Linux中檢測桌面環境C
- 17. 以編程方式檢測MS Word文檔中的更改
- 18. 如何以編程方式更改UIView?
- 19. 如何以編程方式更改android:configChanges?
- 20. 如何檢查VB.NET中的IP地址更改?
- 21. 以編程方式檢測視圖即將更改的時間。
- 22. 如何在iphone地址簿中以編程方式保存家庭地址?
- 23. 以編程方式更改Windows中的NameServer TCP/IP
- 24. 如何更改phpmyadmin MySQL的IP地址?
- 25. 如何更改UdpClient IP地址?
- 26. 如何更改eve的IP地址?
- 27. 檢測登錄用戶的IP地址更改
- 28. 檢測接口上的IP地址更改
- 29. 如何以編程方式在Qt中更改網絡模式
- 30. 在C#中更改IP地址
+1:常見問題,很高興看到它在這裏問。 – 2009-02-24 10:51:45
丹尼,恕我直言,如果你的解決方案沒有投票,那麼什麼是?你顯然會等待從套接字收到一個特定的消息,當一個人可以簡單地輪詢ifconfig的輸出或使用其他人建議的getifaddrs時,安靜地複雜化 – user3529114 2014-04-13 13:54:27