2014-10-31 48 views
0

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

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:”);打印“成功”...

回答

1

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

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

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

+0

谢谢你的帮助! :) – testermaster 2014-10-31 01:26:06

+0

原因可以做两个写与Nagle算法无关。你可以关闭Nagle并再次进行实验。 – meteorgan 2015-09-25 15:49:14