在封闭连接上写入不会立即生成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(“错误:”); 打印“成功”……

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

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

你必须做两次写操作的原因可能是因为Nagle的算法 。 为避免过多的网络开销,TCP尝试将短消息组合到一个段中。 维基百科页面包含一些解决方法。