在关闭的插座写不会立刻产生SIGPIPE [英] write on closed socket doesn't generate sigpipe immediatly

查看:195
本文介绍了在关闭的插座写不会立刻产生SIGPIPE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个问题,在我的C.服务器/客户端如果我一个SIGINT后关闭服务器套接字,然后我尝试从客户端这个封闭套接字写之前比,我已经做写两次客户端生成SIGPIPE。难道不应该立刻产生的呢?这是一种正常的行为或东西我需要解决?这是我的code。我在Ubuntu上,同一台电脑测试的东西,通过127.0.0.1连接。

I've this problem with my server/client on C. If I close the server socket after a SIGINT, and then I try to write on this closed socket from the client, I've to do write two times before than client generates SIGPIPE. Shouldn't it generate it immediatly? Is this a normal behaviour or something I need to fix? This is my code. I'm testing things on ubuntu, same PC, connecting via 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

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作品(Erorr:);打印成功...

The problem is that when I close the server terminal with CTRL+C, the first write on the socket from the client works without any problem... perror("Erorr:"); prints "success"...

推荐答案

TCP协议不提供接收机转告寄件人,它的关闭连接的方法。当它关闭连接,它发送一个 FIN 段,但这只是意味着它的完成发送,而不是它无法再接收。

The TCP protocol doesn't provide a way for the receiver to tell the sender that it's closing the connection. When it closes the connection, it sends a FIN segment, but this just means that it's done sending, not that it can no longer receive.

发送者检测到连接已关闭的方式是,它试图发送数据,和接收器发回一个 RST 段中的反应。但是写入套接字不等待响应,它只是队列中的数据,并立即返回。出现该信号时, RST 被接收,这将是一个短的时间后。

The way the sender detects that the connection has been closed is that it tries to send data, and the receiver sends back a RST segment in response. But writing to a socket doesn't wait for the response, it just queues the data and returns immediately. The signal occurs when the RST is received, which will be a short time later.

究其原因,你必须做两写入可能是因为 Nagle算法。为了避免过多的网络开销,TCP尝试短消息组合成一个单一的段。维基百科页面包括一些这方面的解决办法。

The reason you have to do two writes may be because of Nagle's Algorithm. To avoid excessive network overhead, TCP tries to combine short messages into a single segment. The Wikipedia page includes some workarounds for this.

这篇关于在关闭的插座写不会立刻产生SIGPIPE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆