4

我有一个程序可以将数据发送到带有 android 的手机。让我们开始吧

//编辑

while(enviado < length) {
    printf("SEND\n");
    r = write(con, buff_enviar+enviado, length-enviado);
    printf(" OK\n");
    if (r > 0) enviado += r;
    else if (r == 0) { printf(" * >> Socket cerrado [datos] (%d)\n",r); return r; }
    else if (r == -1) { printf(" * >> Error [datos] (%d)\n",r); return r; }
}

当我离开这段时间时,我会改变buff_enviar价值观。当我通过成功的 socket.close() 取消手机中的传输时,这write会使我的程序无缘无故地结束。所以我的程序的输出是:

SEND OK SEND OK SEND

我想这是write错的,因为它没有 printf OK。ERRNO 值为 61(无可用数据)

我希望有人以前遇到过这个问题并解决了它。

编辑:有时当我取消时,r = -1 所以我可以处理错误,但大多数时候它只是终止程序。就像随机选择的一样。我很困惑 :(

亲切的问候,劳尔

4

3 回答 3

9

您正在写入一个已关闭的套接字,该套接字默认会生成一个“断管”信号 ( SIGPIPE)。为了能够可靠地从 中恢复write(),您需要EPIPE通过调用来忽略:

signal (SIGPIPE, SIG_IGN);

程序中的某处,例如main().

于 2013-04-20T19:15:13.780 回答
7

尽管选择的答案是忽略整个信号过程,但还有其他选择:

使用send功能MSG_NOSIGNAL

send(con, buff_enviar+enviado, length-enviado, MSG_NOSIGNAL);

SIGPIPE在套接字级别禁用(并非在所有内核上都可用):

int flag = 1;
setsockopt(con, SOL_SOCKET, SO_NOSIGPIPE, &flag, sizeof(flag));

禁用SIGPIPE调用者线程:

sigset_t set;
sigemptyset (&set);
sigaddset (&set, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &set, NULL);

最后,禁用整个进程的信号(不推荐用于库):

signal(SIGPIPE, SIG_IGN);
于 2013-04-20T19:44:06.630 回答
0

同样在我的情况下,没有核心转储的程序有很多崩溃

信号(SIGPIPE,SIG_IGN);

程序开头的这一行已经解决了这个问题!

于 2021-06-29T05:08:38.827 回答