2011-09-27 13 views
12

Estoy intentando compilar este programa, como se indica en la Guía del Beej a la red Programación en la página 19.netdb.h no vinculan adecuadamente

#include <stdio.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <sys/socket.h> 

int main() { 
    int status; 
    struct addrinfo hints; 
    struct addrinfo *servinfo;   /* Will point to the results */ 
    memset(&hints, 0, sizeof hints); /* Make sure the struct is empty */ 
    hints.ai_family = AF_UNSPEC;  /* Don't care IPv4 or IPv6 */ 
    hints.ai_socktype = SOCK_STREAM; 
    hints.ai_flags = AI_PASSIVE; 

    if ((status = getaddrinfo(NULL, "3490", &hints, &servinfo)) != 0) { 
     fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status)); 
     exit(1); 
    } 

    /* Servinfo now points to a linked list of 1 or more struct addrinfos 
     ... do everything until you don't need servinfo anymore .... */ 

    freeaddrinfo(servinfo); /* Free the linked-list */ 

    return 0; 
}  

Entre otros errores, veo

../main.c:8:18: error: storage size of ‘hints’ isn’t known 
../main.c:13:19: error: ‘AI_PASSIVE’ undeclared (first use in this function) 
../main.c:16:3: warning: implicit declaration of function ‘gai_strerror’ 

Parece que gcc no está enlazando con netdb.h. Eclipse, el IDE que estoy usando para compilar esto, no tiene problemas para encontrar el archivo. Aquí está el comando del compilador:

gcc -O0 -g3 -pedantic -Wall -c -fmessage-length=0 -ansi -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.c" 

Adición -lnetdb no resuelve el problema. Además ...

~> find /usr/include/ -name netdb.h 
/usr/include/bits/netdb.h 
/usr/include/gssrpc/netdb.h 
/usr/include/netdb.h 
/usr/include/rpc/netdb.h 

Creo que estos archivos vienen preinstalados en mi host de openSUSE. ¿Por qué no detecta gcc netdb.h? ¿O estoy sacando la conclusión equivocada?

Respuesta

17
../main.c:8:18: error: storage size of ‘hints’ isn’t known 
../main.c:13:19: error: ‘AI_PASSIVE’ undeclared (first use in this function) 
../main.c:16:3: warning: implicit declaration of function ‘gai_strerror’ 

Parece que gcc no es la vinculación con netdb.h ....

Estos no están vinculando errores, y no se necesita un objeto de archivo NetDB compartida (no existe tal bestia; netdb.h simplemente define estructuras de datos y macros para usar en su código).

Estos son los errores de compilación: gcc quejándose porque usted está utilizando nombres que no reconoce (AI_PASSIVE) y tipos de datos para los que la estructura se desconoce (struct addrinfo).

Parece que el código tal como lo presentó es correcto, y addrinfo se define en /usr/include/netdb.h. ¿Qué pasa si se compila así:

gcc -c main.c 

¿Todavía conseguir el mismo comportamiento? Si es así, echa un vistazo a la salida de :

gcc -E main.c 

Esto genera una versión preprocesado del código, con todos los #include declaraciones reemplazados por su contenido real.Usted debe ser capaz de grep a través de este y ver si el compilador está consiguiendo realmente /usr/include/netdb.h si si se trata de encontrar algo más:

$ gcc -E foo.c | grep netdb.h | awk '{print $3}' | sort -u 

Cuál de mis rendimientos del sistema:

"/usr/include/bits/netdb.h" 
"/usr/include/netdb.h" 
"/usr/include/rpc/netdb.h" 

Cuando se agrega -ansi a la línea de comandos, está cambiando la forma en que gcc se comporta de manera que romperá el kernel de Linux y muchos archivos de encabezado del sistema . La definición de addrinfonetdb.h está protegido así:

#ifdef __USE_POSIX 
/* Structure to contain information about address of a service provider. */ 
struct addrinfo 
{ 
    int ai_flags;     /* Input flags. */ 
    int ai_family;    /* Protocol family for socket. */ 
    int ai_socktype;    /* Socket type. */ 
    int ai_protocol;    /* Protocol for socket. */ 
    socklen_t ai_addrlen;   /* Length of socket address. */ 
    struct sockaddr *ai_addr;  /* Socket address for socket. */ 
    char *ai_canonname;   /* Canonical name for service location. */ 
    struct addrinfo *ai_next;  /* Pointer to next in list. */ 
}; 

// ...other stuff... 
#endif 

Cuando se ejecuta gcc con la bandera -ansi, este undefines la __USE_POSIX macro, porque las cosas protegidos por el presente pueden no ser estrictamente ANSI compatible. Se puede ver la diferencia si se compara este :

gcc -E /usr/include/netdb.h 

Con esta:

gcc -E -ansi /usr/include/netdb.h 

Sólo el primero contiene la estructura addrinfo.

+0

Obtengo los mismos tres archivos de encabezado como salida. Veo estos errores de compilación: http://pastebin.com/jVVMqftA – Pieter

+1

Entonces ... ¿está funcionando? Es decir, no está viendo ningún error relacionado con 'netdb.h', y ¿está recibiendo una advertencia sobre' memset() '? Eso suena como progreso. La advertencia 'memset()' significa que necesita '#include ' (esto viene de la página de comando man' memset (3) '). – larsks

+0

No veo ninguna advertencia o error si incluyo 'string.h' también. Sin embargo, quiero que mi código sea compatible con ANSI C, así que sigo recibiendo estos errores ... http://pastebin.com/B21NyGQ9 – Pieter

0

La vinculación no asocia un archivo de encabezado al programa, procesa previamente los archivos de cabecera de los manejadores.

La vinculación asocia bibliotecas de objetos compartidos (mira en/usr/lib) a los objetos compilados. Algunas veces no basta con agregar "-lnetdb" ya que la biblioteca podría no estar en la ruta del enlazador. En ese caso, debe usar un -L (ruta) para agregar una entrada de ruta para que la directiva "-lnetdb" pueda encontrar el archivo netdb.so correcto.

+0

Parece que no tengo un objeto compartido llamado '* netdb *' en esa carpeta ... http://pastebin.com/9GPmFehC ¿Cómo puedo obtener los archivos SO que me faltan? ? – Pieter

2

añadir en la parte superior de su archivo

#define _XOPEN_SOURCE 600 
0

Uso #include <netinet/in.h> .... junto con eso ..... y en la compilación (ubuntu) ....

gcc server/client -o server/client.c -lpthread 

(aquí lpthread es un hilo de procesamiento linki) ... que resuelve su problema. :-D

Cuestiones relacionadas