在封闭连接上写入不会立即生成sigpipe

时间:2014-10-31 00:19:25

标签: c sockets signals sigpipe

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

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("错误:");打印"成功" ...

1 个答案:

答案 0 :(得分:3)

TCP协议没有为接收方提供告诉发送方它正在关闭连接的方法。当它关闭连接时,会发送FIN段,但这只表示它已完成发送,而不是它已无法再接收。

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

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