2013-09-21 5 views
24

मैं पॉज़िक्स सॉकेट के आधार पर एक क्लाइंट प्रोग्राम लिखता हूं। कार्यक्रम एकाधिक धागे बनाता है और सर्वर को लॉक करने जा रहा है। लेकिन gdb समय में डिबग के दौरान कार्यक्रम (त्रुटि) "(gdb) nप्रोग्राम सिग्नल सिगिप, टूटी पाइप प्राप्त हुआ।

कार्यक्रम संकेत प्राप्त SIGPIPE, टूटी पाइप। __kernel_vsyscall में 0xb7fdd424() ([ 0xb74c0b40 (LWP 4864) थ्रेड पर स्विच किया जा] एक जानकारी देता है 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; 
} 

कि यह क्या है और क्या करना है?

उत्तर

30

प्रक्रिया को SIGPIPE प्राप्त हुआ। इस सिग्नल के लिए डिफ़ॉल्ट व्यवहार प्रक्रिया को समाप्त करना है।

SIGPIPE एक प्रक्रिया में भेजा जाता है अगर उसने सॉकेट को लिखने की कोशिश की जो लिखने के लिए बंद कर दिया गया था या अब कनेक्ट नहीं है (अब)।

कि इस कार्यक्रम के इस मामले में समाप्त होता है से बचने के लिए, आप या तो

  • प्रक्रिया की अनदेखी SIGPIPE या
  • SIGPIPE के लिए एक स्पष्ट हैंडलर इंस्टॉल (आमतौर पर कुछ नहीं कर रहा) बना सकते हैं।

दोनों ही मामलों send*()/write() में -1 लौट सकते हैं और EPIPE करने के लिए errno स्थापित करेगा। जब 'gdb' के साथ डिबगिंग

#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); 
+0

यह काम करेगा? अगर (सिग्नल (सिगिपिप, सिग्नलहैंडलर) == ईआईएनवीएएल) मुझे त्रुटि -1 और ईपीआईपीई कैसे मिलेगा। – jongbanaag

+0

@ ड्रेफस 15: सिग्नल हैंडलर्स को कैसे डालना है, इस बारे में अनिश्चितताओं को स्पष्ट करने के लिए कृपया इस पर एक और प्रश्न पोस्ट करें। – alk

3

आपने एक ऐसे कनेक्शन को लिखा है जो पहले से ही सहकर्मी द्वारा बंद कर दिया गया है।

13

SIGPIPE का संभावित हल, तो आप इस कोड से यह संकेत अनदेखा कर सकते हैं मैन्युअल SIGPIPE निष्क्रिय करने के लिए इस प्रकार है:

(gdb) संभाल SIGPIPE nostop

+6

सिगिपिप के लिए आपका सिग्नल हैंडलर stdout को एक संदेश लिखता है। लेकिन मान लीजिए कि स्टडआउट को लिखना सिगिपिप को पहली जगह क्यों हुआ ...? – tetsujin

+1

सिग्नल हैंडलर से गैर-पुनर्वित्तक स्टडीओ का उपयोग सुरक्षित नहीं है। – ulix

2

मैं exp की तरह एक ही समस्या से विचलित हो गया और यह मुझे इस एसओ पोस्ट में जाने दिया। मुझे स्पिनैडिक सिगिप सिग्नल मिला जो मेरे फास्टसी सी प्रोग्राम के क्रैश को nginx द्वारा चलाया गया। मैंने भाग्य के बिना signal(SIGPIPE, SIG_IGN); करने की कोशिश की, यह दुर्घटनाग्रस्त हो गया।

कारण यह था कि nginx के temp dir की अनुमति समस्या थी। अनुमतियों को ठीक करने से SIGPIPE समस्या हल हो गई। Details here on how to fix और more here

संबंधित मुद्दे