V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
chashao
V2EX  ›  问与答

阅读 UNIX 网络编程卷一,有一道课后题不会,求大佬指点

  •  
  •   chashao · 2018-05-01 16:00:58 +08:00 · 1300 次点击
    这是一个创建于 2433 天前的主题,其中的信息可能已经有所发展或是发生改变。
    题目:11.11 如果找不到给定 IP 地址对应的主机名,gethostbyaddr 可能就得花很长时间(最长 80s)才能返回一个错误.编写一个新的名为 getnameinfo_timeo 的函数,它有一个额外的整数参数用于指定等待应答的最大秒数.如果发生超时并且没有设置 NI_NAMEREQD 标志,那就调用 inet_ntop 返回一个地址串.

    我的问题是如何实现 timeout 功能?
    5 条回复    2018-05-01 16:44:02 +08:00
    seaswalker
        1
    seaswalker  
       2018-05-01 16:06:15 +08:00 via iPhone
    猜一下,定时器?
    XiaoxiaoPu
        2
    XiaoxiaoPu  
       2018-05-01 16:07:32 +08:00   ❤️ 1
    简单的方法就是多线程呗,起一个线程去调用 gethostbyaddr,主线程等待 timeout,超时了就把子线程杀掉,然后返回
    geelaw
        3
    geelaw  
       2018-05-01 16:24:13 +08:00   ❤️ 3
    如果你用纯粹的 UNIX,似乎只有比较低效的方式,而且很容易受其他正在运行的子进程的干扰。

    思路是这样的:fork 两个子进程,一个等待 timeout 那么多秒,另一个调用 gethostbyaddr,并尝试把结果告诉主进程(共享内存或者匿名管道),主进程用 wait,在其中一个子进程结束的时候就可以返回,所以是 whichever comes first,接下来可以杀掉另一个子进程并根据结果返回。

    问题:如果调用这个东西之前 fork 出来了子进程,那么 wait 可能会拿到不是你控制(创建)的子进程的结果。

    如果你的环境支持比 POSIX 更多的 API set,你可以尝试使用 WaitForMultipleObjectsEx 的等价物。
    chashao
        4
    chashao  
    OP
       2018-05-01 16:39:29 +08:00
    @geelaw 我看书 301 页对于 connect 的设置超时代码,能不能换成 gethostbyaddr
    ```c
    static void getnameinfo_alarm(int signo) {
    return;
    }
    int getnameinfo_timeo(const struct sockaddr *sockaddr, socklen_t addrlen,
    char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flag, int timeout){
    Sigfunc *sigfunc;
    sigfunc = Signal(SIGALRM, getnameinfo_alarm);
    if (alarm(timeout) != 0) {
    err_msg("alarm is aready set!");
    }
    int ret;
    if ((ret = getnameinfo(sockaddr, addrlen, host, hostlen, serv, servlen, flag)) != 0) {
    printf("getnameinfo error:%s", gai_strerror(ret));
    }
    alarm(0);
    Signal(SIGALRM, sigfunc);
    return ret;
    }
    ```
    geelaw
        5
    geelaw  
       2018-05-01 16:44:02 +08:00   ❤️ 1
    重新翻了一下 - - 发现有 waitpid,那一个土鳖的方法是循环 waitpid WNOHANG + sleep 直到超时到了。并没想过用 signal/alarm。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2607 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 10:26 · PVG 18:26 · LAX 02:26 · JFK 05:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.