一旦我打电话socket();bind()(具有特定的IP地址,而不是INADDR_ANY);listen(),似乎无法确定 IP 地址是否仍然是系统接口之一的有效地址。
我研究过使用什么:
getsockopt(SO_ERROR)使用;检查错误epoll()对某些EPOLLERR,EPOLL{,RD}HUP事件使用-ing;accept()当进程在此系统调用上被阻止时,如果 IP 地址被删除,会返回错误;上述这些似乎都没有检测到 IP 地址消失和/或接口状态的变化。
bind()一些定时器回调来定期检查IP地址是否可以绑定,但这需要创建另一个套接字,这是不可行的。我没有测试这些:
设置SO_BINDTODEVICE的目的是希望在接口出现故障/IP 地址被删除的情况下,这将改变第一个三元组中设施的行为。
调用ioctl()类似SIOCSPGRP或 的FIOASYNC函数,因为它们承诺向进程发出有关异步事件的信号,希望这些事件包括 IP 地址的消失。
用于netlink获取路由表事件,但这是 Linux 特定的。
我希望有一种更便携的方式。
我需要的是一些类似于 的事件RDMA_CM_EVENT_DEVICE_REMOVAL,但是AF_INET当没有与该 IP 地址绑定的接口时,套接字会通知我。即使这样也可能无法实现,因为bind()如果接口关闭,即使完成也不会出现错误。
先决条件:
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
#define list_next_entry(pos, member) \
list_entry((pos)->member.next, typeof(*(pos)), member)
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
#define list_entry_is_head(pos, head, member) \
(&pos->member == (head))
#define list_for_each_entry(pos, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member); \
!list_entry_is_head(pos, head, member); \
pos = list_next_entry(pos, member))
Run Code Online (Sandbox Code Playgroud)
struct A,其中包含 type 结构列表的头部struct B。问:我们假设offsetof(struct B, entry_in_list) > …