Linux-Socket编程-TCP非阻塞方式02


  • 测试程序tcp_server2-1/tcp_client2-1,连接成功后,client 发数据(每次10 字节,间隔1 秒),server 用大小100 的缓冲区收数据,死循环运行

  • 此时在client(server)端按CTRL+C,server(client)端能否检测到连接中断?

    client端ctrl+c后,server的connectfd仍可读,但是read函数返回0,说明client端已经关闭连接。

    client端ctrl+c,运行示例:

    server端ctrl+c后,client端会收到SIGPIPE信号,说明server已经关闭连接。

    当服务器close一个连接时,若client端接着发数据。根据TCP协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。

    根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止、退出),所以client会退出。

    若不想客户端退出可以把SIGPIPE设为SIG_IGN。如:signal(SIGPIPE,SIG_IGN);这时SIGPIPE交给了系统处理。

    signal设置的信号句柄只能起一次作用,信号被捕获一次后,信号句柄就会被还原成默认值了。
    sigaction设置的信号句柄,可以一直有效,直到你再次改变它的设置。

    struct sigaction action;
    action.sa_handler = handle_pipe;
    sigemptyset(&action.sa_mask); //清空此信号集
    action.sa_flags = 0;
    sigaction(SIGPIPE, &action, NULL);
    

    server端ctrl+c,运行示例:

  • 如果新开一个会话窗口,用kill -9 杀client(server)端程序,server(client)端能否检测到连接中断?

    kill -9 结果与ctrl+c一样。

    kill -9 client

    kill -9 server

  • 测试程序tcp_server2-2/tcp_client2-2,连接成功后,server 发数据(每次10 字节,间隔1 秒),client 用大小100 的缓冲区收数据,死循环运行(同时观察2-1 的两种中断检测方式)

    与2-1一样,无论是ctrl+c或者kill -9, 一端关闭,若另一端在读数据,select返回rdfs有效,但是read返回0,判断为关闭; 一端关闭,若另一端在写,会收到SIGPIPE信号。

    client端ctrl+c,运行示例:

    server端ctrl+c,运行示例:

    kill -9 client,运行示例:

    kill -9 server,运行示例: