42

我编写了一个基于 posix 套接字的客户端程序。该程序创建多个线程并将锁定服务器。但是在gdb时间调试期间,程序给出了一个信息(错误)

(gdb) n
Program received signal SIGPIPE, Broken pipe. [Switching to Thread 0xb74c0b40 (LWP 4864)] 0xb7fdd424 in __kernel_vsyscall () 
(gdb) 

这是代码:

#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

int get_hostname_by_ip(char* h , char* ip)
{
    struct hostent *he;
    struct in_addr **addr_list;
    int i;

    if ((he = gethostbyname(h)) == NULL) 
    {
        perror("gethostbyname");
        return 1;
    }
    addr_list = (struct in_addr **) he->h_addr_list;
    for(i = 0; addr_list[i] != NULL; i++) 
    {
        strcpy(ip , inet_ntoa(*addr_list[i]) );
        return 0;
    }

    return 1;
}

void client(char* h, int s)
{
    int fd;
    struct sockaddr_in addr;
    char ch[]="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    fd = socket(AF_INET, SOCK_STREAM, 0);
    addr.sin_family=AF_INET;
    char* ip = new char[20];
    get_hostname_by_ip(h, ip);
    addr.sin_addr.s_addr=inet_addr(ip);
    int port = 80;
    addr.sin_port=htons(port);
    if(connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) 
    {
        perror("connect error");
        return;
    }
    while(1)
    {
        if(send(fd, ch, sizeof(ch), 0) < 0)
        {   
            perror("send");
        }
    }
    //char buffer[1024];
    //if(recv(fd, &buffer, sizeof(buffer), 0) < 0)
    //{ 
    //  perror("recive");
    //}

    //printf("nReply from Server: %s\n", buffer);
    close(fd);
}

struct info
{
    char* h;
    int c;
};


void* thread_entry_point(void* i)
{
    info* in = (info*)i;
    client(in->h, in->c);
}

int main(int argc, char** argv)
{
    int s = atoi(argv[2]);
    pthread_t t[s];
    info in = {argv[1], s};
    for(int i = 0; i < s; ++i)
    {
        pthread_create(&t[i], NULL, thread_entry_point, (void*)&in);
    }
    pthread_join(t[0], NULL);

    return 0;
}

它是什么以及该怎么做?

4

5 回答 5

60

该进程收到一个SIGPIPE. 此信号的默认行为是结束进程。

SIGPIPE如果 A尝试写入已关闭以进行写入或未连接(不再连接)的套接字,则将A发送到进程。

为避免程序在这种情况下结束,您可以

  • 让进程忽略SIGPIPE

    #include <signal.h>
    
    int main(void)
    {
      sigaction(SIGPIPE, &(struct sigaction){SIG_IGN}, NULL);
    
      ...
    

    或者

  • SIGPIPE为(通常什么都不做)安装一个显式处理程序:

    #include <signal.h>
    
    void sigpipe_handler(int unused)
    {
    }
    
    int main(void)
    {
      sigaction(SIGPIPE, &(struct sigaction){sigpipe_handler}, NULL);
    
      ...
    

在这两种情况下send*()/write()都会返回-1并设置errnoEPIPE.

于 2013-09-23T15:27:38.830 回答
33

使用“gdb”进行调试时,可以手动禁用 SIGPIPE,如下所示:

(gdb) 处理 SIGPIPE nostop

于 2015-05-12T16:56:26.827 回答
12

SIGPIPE 的解决方法,您可以通过以下代码忽略此信号:

#include <signal.h>

/* Catch Signal Handler functio */
void signal_callback_handler(int signum){

        printf("Caught signal SIGPIPE %d\n",signum);
}

在您的代码中(主要或全局)

/* Catch Signal Handler SIGPIPE */
signal(SIGPIPE, signal_callback_handler);
于 2014-02-22T15:52:49.403 回答
5

您已写入已被对等方关闭的连接。

于 2013-09-22T01:03:00.983 回答
3

我遇到了同样的问题,它让我看到了这个 SO 帖子。我收到零星的 SIGPIPE 信号,导致我的由 nginx 运行的 fastcgi C 程序崩溃。我试过signal(SIGPIPE, SIG_IGN);没有运气,它一直在崩溃。

原因是nginx的临时目录有权限问题。修复权限解决了 SIGPIPE 问题。此处有关如何修复的详细信息以及此处的更多信息。

于 2016-05-23T21:20:24.803 回答