程序收到信号 SIGPIPE, Broken pipe [英] Program received signal SIGPIPE, Broken pipe

查看:44
本文介绍了程序收到信号 SIGPIPE, Broken pipe的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<块引用>

(gdb) n程序收到信号 SIGPIPE,断管.[切换到线程 0xb74c0b40 (LWP 4864)] __kernel_vsyscall() 中的 0xb7fdd424(gdb)

代码如下:

#include #include #include #include #include #include #include #include #include #include int get_hostname_by_ip(char* h , char* ip){struct hostent *he;结构 in_addr **addr_list;国际我;if ((he = gethostbyname(h)) == NULL){perror("gethostbyname");返回 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]));返回0;}返回 1;}无效客户端(char * h,int s){国际金融;结构 sockaddr_in 地址;char ch[]="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";fd = 套接字(AF_INET,SOCK_STREAM,0);addr.sin_family=AF_INET;字符* ip = 新字符[20];get_hostname_by_ip(h, ip);addr.sin_addr.s_addr=inet_addr(ip);int 端口 = 80;addr.sin_port=htons(port);if(connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0){perror("连接错误");返回;}同时(1){if(send(fd, ch, sizeof(ch), 0) <0){perror("发送");}}//字符缓冲区[1024];//if(recv(fd, &buffer, sizeof(buffer), 0) <0)//{//perror("接收");//}//printf("nReply from Server: %s
", buffer);关闭(FD);}结构信息{字符* h;国际 c;};void* thread_entry_point(void* i){info* in = (info*)i;客户端(输入-> h,输入-> c);}int main(int argc, char** argv){int s = atoi(argv[2]);pthread_t t[s];信息在 = {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);返回0;}

它是什么以及做什么?

解决方案

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

SIGPIPE 被发送到一个进程,如果它试图写入一个已关闭写入或未连接(不再连接)的套接字.

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

  • 使进程忽略SIGPIPE

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

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

    #include void sigpipe_handler(int 未使用){}int main(void){sigaction(SIGPIPE, &(struct sigaction){sigpipe_handler}, NULL);...

在这两种情况下,send*()/write() 都会返回 -1 并将 errno 设置为EPIPE.

I write a client program based on posix sockets. The program creates multiple threads and is going to lock the server. But during debug in gdb time the program gives an info (error)

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

Here's the code:

#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
", 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;
}

What it is and what to do?

解决方案

The process received a SIGPIPE. The default behaviour for this signal is to end the process.

A SIGPIPE is sent to a process if it tried to write to a socket that had been shutdown for writing or isn't connected (anymore).

To avoid that the program ends in this case, you could either

  • make the process ignore SIGPIPE

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

    or

  • install an explicit handler for SIGPIPE (typically doing nothing):

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

In both cases send*()/write() would return -1 and set errno to EPIPE.

这篇关于程序收到信号 SIGPIPE, Broken pipe的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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