网络事件侦测

更新时间:
2024-03-14
下载文档

网络事件侦测

在网络传输的过程中,网络接口可能被增加或者删除,数据在传输过程中,链路突然断开等,以上这些突发情况,通常会对网络造成致命的错误。为了减少这些问题造成的损失,需要应用程序做一些应对的措施,例如,如果链路突然断开,应该等待网络恢复并重传,一些网络协议支持重传机制,但是它们都有一个共同的特点:重传的次数是有限制的。因此应该有一种机制:当网络恢复的时候通知应用程序进行重传,这种机制有以下一些优点:

  • 网络断开后不会占用太多的 CPU 时间(轮询检测网络状态)。
  • 能够及时地察觉网络的恢复(类似于中断机制)。
  • 对于应用程序重传是可控的(网络协议不可控)。

SylixOS 实现了这种机制,它被称作网络事件侦测。通过操作 SylixOS 标准 I/O 设备“/dev/netevent”来侦测网络事件。这意味着可以像操作普通文件一样来操作此设备以获得网络的事件通知,应用程序唯一需要了解的是事件的帧格式,如下图所示。

一个 SylixOS 网络事件占用 24 个字节的空间,这意味着应用程序至少需要 24 个字节的空间来接收一个网络事件。在这 24 个字节中,前 4 个字节存放了事件的类型如下表所示,需要注意的是,事件类型以大端字节序存放在前 4 个字节中,事件类型后的 4 个字节存放了一个网络接口名(如 en1),其他空间存放了其他数据。通常应用程序可通过以下形式获得一个网络事件类型(buf 是应用程序接收缓冲区)。

event = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]);

SylixOS 支持如下表所示的网络事件。

网络事件类型说明
NET_EVENT_ADD网卡添加
NET_EVENT_REMOVE网卡删除
NET_EVENT_UP网卡使能
NET_EVENT_DOWN网卡禁能
NET_EVENT_LINK网卡已连接
NET_EVENT_UNLINK网卡断开连接
NET_EVENT_ADDR网卡地址变化
NET_EVENT_AUTH_FAIL网卡认证失败
NET_EVENT_AUTH_TO网卡认证超时
NET_EVENT_PPP_DEAD连接停止
NET_EVENT_PPP_INIT进入初始化过程
NET_EVENT_PPP_AUTH进入用户认证
NET_EVENT_PPP_RUN网络连通
NET_EVENT_PPP_DISCONN进入连接中断
NET_EVENT_WL_QUAL网卡无线环境变化(信号强度等)
NET_EVENT_WL_SCAN无线网卡 AP 扫描结束

下面程序展示了应用程序如何侦测一个网络事件。在程序的实现中,首先打开设备 NET_EVENT_DEV_PATH 并安装 SIGALRM 信号,2 秒后使网卡禁能,read 函数读取网络事件并返回,最后打印网络接口和事件类型。

#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <net/if_event.h>
void show_eventype (int  event)
{
    switch (event) {
    case NET_EVENT_UP:
        fprintf(stdout, "event: up.\n");
        break;
    case NET_EVENT_DOWN:
        fprintf(stdout, "event: down.\n");
        break;
    case NET_EVENT_LINK:
        fprintf(stdout, "event: link.\n");
        break;
    case NET_EVENT_UNLINK:
        fprintf(stdout, "event: unlink.\n");
        break;
    default:
        fprintf(stdout, "event unknown\n");
    }
    system("ifup en1");
}
void sig_handler (int signum)
{
    system("ifdown en1");
}
int main (int argc, char *argv[])
{
    int             fd;
    char            buf[512];
    char            ifname[5];
    ssize_t         len;
    int             event;
    fd = open(NET_EVENT_DEV_PATH, O_RDONLY);
    if (fd < 0) {
        perror("open");
        return  (-1);
    }
    signal(SIGALRM, sig_handler);
    alarm(2);
    len = read(fd, buf, 512);
    if (len < 0) {
        perror("read");
        return  (-1);
    }
    event = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]);
    ifname[0] = buf[4];
    ifname[1] = buf[5];
    ifname[2] = buf[6];
    ifname[3] = buf[7];
    ifname[3] = 0;
    fprintf(stdout, "ifname: %s\n", ifname);
    show_eventype(event);
    return  (0);
}

在 SylixOS Shell 下运行程序,运行结果如下:

# ./Detect_network_events
net interface "en1" set down.
ifname: en1
event: down.
net interface "en1" set up.
文档内容是否对您有所帮助?
有帮助
没帮助