netdb.h没有正确链接

我正在尝试编译这个程序,如第19页的Beej网络编程指南中所述

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

在其他错误中,我看到了

 ../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' 

似乎gcc没有与netdb.h链接。 Eclipse,我用来构建它的IDE,可以轻松找到该文件。 这是编译器命令:

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

添加-lnetdb无法解决问题。 也…

 ~> 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 

我认为这些文件是在我的openSUSE主机上预装的。 为什么gcc没有检测到netdb.h ? 或者我得出了错误的结论?

 ../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' 

看来gcc没有与netdb.h链接….

这些不是链接错误,并且您不需要netdb共享对象文件(没有这样的野兽; netdb.h只是定义了在您的代码中使用的数据结构和宏)。

这些是编译器错误:gcc抱怨因为您使用的是无法识别的名称( AI_PASSIVE )和结构未知的数据类型( struct addrinfo )。

您提供的代码似乎是正确的, addrinfo/usr/include/netdb.h定义。 如果你这样编译它会发生什么:

 gcc -c main.c 

你还有同样的行为吗? 如果是这样,看一下输出:

 gcc -E main.c 

这会生成代码的预处理版本,所有#include语句都会被其实际内容替换。 你应该能够通过这个来查看编译器是否实际上正在获取/usr/include/netdb.h ,如果它找到了其他东西:

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

哪个在我的系统上产生:

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

-ansi添加到命令行时,您正在改变gcc行为方式,这将破坏Linux内核和许多系统头文件。 netdb.haddrinfo定义受到如下保护:

 #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 

当您使用-ansi标志运行gcc时,这将__USE_POSIX定义__USE_POSIX宏,因为__USE_POSIX保护的内容可能不严格符合ANSI标准。 如果你比较一下,你可以看到区别:

 gcc -E /usr/include/netdb.h 

有了这个:

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

只有前者包含addrinfo结构。

添加到文件的顶部

 #define _XOPEN_SOURCE 600 

链接不会将头文件附加到程序,预处理句柄文件。

链接将共享对象库(在/ usr / lib中查找)附加到编译对象。 有时仅仅添加“-lnetdb”是不够的,因为库可能不在链接器路径中。 在这种情况下,您需要使用-L(路径)来添加路径条目,以便指令“-lnetdb”可以找到正确的netdb.so文件。

使用#include ….以及…..和编译(ubuntu)….

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

(这里lpthread是一个linki处理线程)…它解决了你的问题。 😀