write(socket,buff,length)会导致崩溃

McD*_*3ld 3 c sockets

我有一个程序,用于向带有android的手机发送数据.我们是iamgine

//编辑

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; }
}
Run Code Online (Sandbox Code Playgroud)

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

SEND OK SEND OK SEND

我猜这是write错的,因为它没有打印好.ERRNO值为61(无数据)

我希望有人之前遇到过这个问题并解决了.

编辑:有时当我取消时,r = -1所以我可以处理错误,但大多数时候它只是终止程序.这就像是随机选择的.我糊涂了 :(

亲切的问候,劳尔

use*_*342 7

您正在写入已关闭的套接字,默认情况下会生成"断开管道"信号(SIGPIPE).为了能够可靠地恢复write(),您需要EPIPE通过调用忽略:

signal (SIGPIPE, SIG_IGN);
Run Code Online (Sandbox Code Playgroud)

程序中的某个地方,例如main().


Val*_*ouk 5

虽然选择的答案是忽略信号流程,但还有其他选择:

使用send功能MSG_NOSIGNAL:

send(con, buff_enviar+enviado, length-enviado, MSG_NOSIGNAL);
Run Code Online (Sandbox Code Playgroud)

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

int flag = 1;
setsockopt(con, SOL_SOCKET, SO_NOSIGPIPE, &flag, sizeof(flag));
Run Code Online (Sandbox Code Playgroud)

禁用SIGPIPE调用者线程:

sigset_t set;
sigemptyset (&set);
sigaddset (&set, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &set, NULL);
Run Code Online (Sandbox Code Playgroud)

最后,在整个流程范围内禁用信号(不推荐用于库):

signal(SIGPIPE, SIG_IGN);
Run Code Online (Sandbox Code Playgroud)