purposes propio para generador español crear como c sockets gdb pthreads sigpipe

c - propio - hashtag generator español



Programa recibido señal SIGPIPE, tubería rota. (5)

Escribo un programa de cliente basado en sockets posix. El programa crea múltiples hilos y bloqueará el servidor. Pero durante la depuración en tiempo gdb el programa da una información (error)

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

Aquí está el código:

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

¿Qué es y qué hacer?


Al depurar con ''gdb'', es posible desactivar SIGPIPE manualmente de la siguiente manera:

(gdb) manejar SIGPIPE nostop


El proceso recibió un SIGPIPE . El comportamiento predeterminado para esta señal es finalizar el proceso.

Un SIGPIPE se envía a un proceso si intentaba escribir en un socket que se había apagado para la escritura o no está conectado (nunca más).

Para evitar que el programa termine en este caso, podría

  • hacer que el proceso ignore SIGPIPE

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

    o

  • instalar un controlador explícito para SIGPIPE (por lo general, no hacer nada):

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

En ambos casos, send*() / write() devolvería -1 y establecería errno en EPIPE .


Experimenté el mismo problema y me dejó esta publicación SO. Obtuve señales esporádicas de SIGPIPE que causaban bloqueos de mi programa fastcgi C ejecutados por nginx. Intenté signal(SIGPIPE, SIG_IGN); sin suerte, siguió estrellándose.

La razón era que el directorio temporal de nginx tenía un problema de permiso. La reparación de los permisos resolvió el problema de SIGPIPE. Los detalles aquí sobre cómo solucionar y más aquí .


Ha escrito una conexión que ya ha sido cerrada por el par.


Una solución para SIGPIPE, puede ignorar esta señal mediante este código:

#include <signal.h> /* Catch Signal Handler functio */ void signal_callback_handler(int signum){ printf("Caught signal SIGPIPE %d/n",signum); }

en tu código (principal o global)

/* Catch Signal Handler SIGPIPE */ signal(SIGPIPE, signal_callback_handler);