当前位置:  技术问答>linux和unix

阻塞读 真有硬伤?

    来源: 互联网  发布时间:2017-05-01

    本文导语:  本帖最后由 shouso888 于 2013-10-30 10:47:40 编辑 捣捣stevens的《Unix 网络编程》后,留下的疑问: 客户端 阻塞于 read; 服务器主机崩溃,来不及做close 发出 FIN。 问:阻塞read 会一直阻塞?而且完全没有任何可能让它...

本帖最后由 shouso888 于 2013-10-30 10:47:40 编辑
捣捣stevens的《Unix 网络编程》后,留下的疑问:

客户端 阻塞于 read; 服务器主机崩溃,来不及做close 发出 FIN。

问:阻塞read 会一直阻塞?而且完全没有任何可能让它返回?因为对端主机崩溃时,只有写操作才能引起
ETIMEOUT,如果是read就会一直阻塞,TCP也不会知道对端已经崩溃。那阻塞read就是个Bug啊,不知道对端崩
溃还一直傻傻的等,用它就是埋下隐患?


|

如果有防火墙或者是通过NAT连接出去的,我就不能确定了。
但是如果两台机器是直接连接的,并且也没有设置SO_KEEPALIVE的话,read永远不会返回的。
以下的测试代码可以说明这一点

/**
 * @file    demo.c
 * @brief   
 */


#include 
#include 
#include 
#include 
#include 

#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 

int  init(void)
{
    FILE *fp;
    char path[PATH_MAX];

    daemon(0, 0);

    signal(SIGCHLD, SIG_IGN);

    close(STDOUT_FILENO);
    close(STDERR_FILENO);
    sprintf(path, "%s/log/demo.log", getenv("HOME"));
    fp = fopen(path, "a+b");
    dup2(STDOUT_FILENO, STDERR_FILENO);

    return 0;
}

int main(int argc, char *argv[])
{
    int servfd, clntfd;
    struct sockaddr_in servaddr, clntaddr;
    socklen_t          servlen,  clntlen;
    int port;
    int keepalive;
    int reuseaddr;
    socklen_t optlen;
    int ret;
    pid_t pid;
    ssize_t len;
    char buf[1024];

    time_t tick;

    keepalive = 0;
    port = 8888;
    if (argc > 1) {
        keepalive = atoi(argv[1]);
        if (keepalive)
            port++;
    }

    init();

    servfd = socket(PF_INET, SOCK_STREAM, 0);
    optlen = sizeof(reuseaddr);
    ret = setsockopt(servfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, optlen);
    if (ret 

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。














站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,