在关闭的连接上写不会立即生成sigpipe [英] write on closed connection doesn't generate sigpipe immediately

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

问题描述

我在C上的服务器/客户端存在此问题.如果我在SIGINT之后关闭服务器套接字,然后尝试从客户端在此关闭的连接上进行写操作,则必须比客户端生成SIGPIPE.它不应该立即生成吗?这是正常现象还是我需要解决的问题?这是我的代码.我正在同一台PC上通过127.0.0.1连接的ubuntu上进行测试.

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 connection from the client, I've to do write two times before than client generates SIGPIPE. Shouldn't it generate it immediately? 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

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

The problem is that when I close the server terminal with CTRL+C, the first write to the connection from the client works without any problem... perror("Error:"); 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尝试将短消息合并为一个段. Wikipedia页面包含一些解决方法.

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天全站免登陆