【问题标题】:write on closed connection doesn't generate sigpipe immediately在关闭的连接上写入不会立即生成 sigpipe
【发布时间】:2014-10-31 00:19:25
【问题描述】:

我的服务器/客户端在 C 上遇到了这个问题。如果我在 SIGINT 之后关闭服务器套接字,然后我尝试从客户端写入这个关闭的连接,我必须比之前写两次客户端生成 SIGPIPE。它不应该立即生成吗?这是正常行为还是我需要解决的问题?这是我的代码。我正在通过 127.0.0.1 连接的同一台 PC 上的 ubuntu 上进行测试。

server.c

sigset_t set;
struct sigaction sign;
int sock_acc;
int sock;

void closeSig(){
    close(sock_acc);
    close(sock);
    exit(1);
}


int main(){
    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    sig.sa_sigaction = &closeSig;
    sig.sa_flags = SA_SIGINFO;
    sig.sa_mask = set;
    sigaction(SIGINT, &sig, NULL);
    //other code to accept the connection from the client
    sigprocmask(SIG_UNBLOCK, &set, NULL);
    //write/read calls
}

client.c

void closeSigPipe(){
    close(ds_sock);
    printf("Stop...");
    exit(1);
}

int main(){
    sigpipe.sa_sigaction = &closeSigPipe;
    sigpipe.sa_flags = SA_SIGINFO;
    sigaction(SIGPIPE, &sigpipe, NULL);
    //other code to connect the server, and write/read calls
}

问题是当我用 CTRL+C 关闭服务器终端时,第一次从客户端写入连接没有任何问题... perror("Error:");打印“成功”...

【问题讨论】:

    标签: c sockets signals sigpipe


    【解决方案1】:

    TCP 协议没有为接收方提供一种方法来告诉发送方它正在关闭连接。当它关闭连接时,它会发送一个FIN 段,但这只是意味着它已经发送完毕,而不是它不能再接收了。

    发送方检测到连接已关闭的方式是尝试发送数据,接收方发回一个RST段作为响应。但是写入套接字不会等待响应,它只是将数据排队并立即返回。该信号在收到RST 时出现,这将是稍后的时间。

    您必须进行两次写入的原因可能是因为Nagle's Algorithm。为了避免过多的网络开销,TCP 尝试将短消息组合成一个单独的段。 Wikipedia 页面包含一些解决方法。

    【讨论】:

    • 之所以能做两次写入与Nagle算法无关。您可以关闭 Nagle 并再次进行实验。
    猜你喜欢
    • 1970-01-01
    • 2012-02-14
    • 2017-03-20
    • 2022-07-30
    • 2017-10-07
    • 1970-01-01
    • 2016-12-04
    • 1970-01-01
    相关资源
    最近更新 更多