netdb.h 未正确链接

发布于 2024-12-06 12:24:47 字数 1724 浏览 0 评论 0原文

我正在尝试编译此程序,如 Beej 的网络编程指南 第 19 页中所引用。

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

除了其他错误之外,我还看到

../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?或者我得出了错误的结论?

I'm trying to compile this program, as referenced in Beej's Guide to Network Programming on page 19.

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

Among other errors, I see

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

It appears that gcc isn't linking with netdb.h. Eclipse, the IDE that I'm using to build this, has no trouble finding the file. Here's the compiler command:

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

Adding -lnetdb doesn't resolve the issue. Also...

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

I think these files came preinstalled on my openSUSE host. Why doesn't gcc detect netdb.h? Or am I drawing the wrong conclusion?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

魄砕の薆 2024-12-13 12:24:47
../main.c:8:18:错误:“提示”的存储大小未知
../main.c:13:19:错误:“AI_PASSIVE”未声明(在此函数中首次使用)
../main.c:16:3:警告:函数“gai_strerror”的隐式声明

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

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

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

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

gcc -c main.c

你还会有同样的行为吗?如果是这样,请查看输出
of:

gcc -E main.c

这会生成代码的预处理版本,其中包含所有
#include 语句替换为其实际内容。你应该是
能够 grep 通过这个并查看编译器是否真正得到
/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.h 中的 addrinfo 定义受到保护
像这样:

#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 宏,因为受此保护的东西可能不会
严格符合 ANSI 标准。如果你比较一下你就会发现差异
this:

gcc -E /usr/include/netdb.h

有了这个:

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

只有前者包含 addrinfo 结构。

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

It appears that gcc isn't linking with netdb.h....

These are not linking errors, and you don't need a netdb shared object
file (there is no such beast; netdb.h simply defines data structures
and macros for use in your code).

These are compiler errors: gcc complaining because you're using names
that it doesn't recognize (AI_PASSIVE) and data types for which the
structure is unknown (struct addrinfo).

The code as you've presented it appears to be correct, and addrinfo
is defined in /usr/include/netdb.h. What happens if you compile it
like this:

gcc -c main.c

Do you still get the same behavior? If so, take a look at the output
of:

gcc -E main.c

This generates a preprocessed version of the code, with all of the
#include statements replaced by their actual content. You should be
able to grep through this and see if the compiler is actually getting
/usr/include/netdb.h if if it's finding something else:

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

Which on my system yields:

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

When you add -ansi to the command line, your are changing the way
gcc behaves in ways that will break the Linux kernel and many system
header files. The addrinfo definition in netdb.h is protected
like this:

#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

When you run gcc with the -ansi flag, this undefines the
__USE_POSIX macro, because things protected by this may not be
strictly ANSI compliant. You can see the difference if you compare
this:

gcc -E /usr/include/netdb.h

With this:

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

Only the former contains the addrinfo structure.

柒七 2024-12-13 12:24:47

添加到文件顶部

#define _XOPEN_SOURCE 600

add at the top of your file

#define _XOPEN_SOURCE 600
ˇ宁静的妩媚 2024-12-13 12:24:47

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

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

Linking doesn't attach a header file to the program, pre-processing handles header files.

Linking attaches shared object libraries (look in /usr/lib) to compiled objects. Sometimes it is not sufficent to just add "-lnetdb" as the library might not be in the linker path. In that case, you need to use a -L(path) to add a path entry so the directive "-lnetdb" can find the correct netdb.so file.

仙气飘飘 2024-12-13 12:24:47

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

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

(此处 lpthread是一个 linki 处理线程)...它解决了你的问题。 :-D

Use #include <netinet/in.h> ....along with that.....and in compilation (ubuntu)....

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

(here lpthread is a linki processing thread)...which solves your problem. :-D

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文