【问题标题】:C89: getaddrinfo() on Windows?C89:Windows 上的 getaddrinfo()?
【发布时间】:2010-02-23 02:10:45
【问题描述】:

我是 C89 新手,正在尝试做一些套接字编程:

void get(char *url) {
    struct addrinfo *result;
    char *hostname;
    int error;

    hostname = getHostname(url);

    error = getaddrinfo(hostname, NULL, NULL, &result);

}

我正在 Windows 上开发。如果我使用这些包含语句,Visual Studio 会抱怨没有这样的文件:

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

我该怎么办?这是否意味着我无法移植到 Linux?

【问题讨论】:

    标签: c windows sockets c89


    【解决方案1】:

    在 Windows 上,除了您提到的包含之外,以下内容就足够了:

    #include <winsock2.h>
    #include <windows.h>
    

    您还必须链接到ws2_32.lib。这样做有点难看,但对于 VC++,你可以通过:#pragma comment(lib, "ws2_32.lib")

    Winsock 和 POSIX 之间的其他一些区别包括:

    • 在使用任何套接字函数之前,您必须调用WSAStartup()

    • close() 现在称为closesocket()

    • 没有将套接字作为int 传递,而是有一个typedef SOCKET 等于指针的大小。您仍然可以使用与 -1 的比较来查找错误,尽管 Microsoft 有一个名为 INVALID_SOCKET 的宏来隐藏它。

    • 对于设置非阻塞标志等操作,您将使用ioctlsocket() 而不是fcntl()

    • 您必须使用send()recv() 而不是write()read()

    至于如果你开始为 Winsock 编码,你是否会失去 Linux 代码的可移植性......如果你不小心,那么是的。但是您可以编写代码来尝试使用#ifdefs..来弥补差距。

    例如:

    #ifdef _WINDOWS
    
    /* Headers for Windows */
    #include <winsock2.h>
    #include <windows.h>
    
    #else
    
    /* Headers for POSIX */
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    
    /* Mimic some of the Windows functions and types with the
     * POSIX ones.  This is just an illustrative example; maybe
     * it'd be more elegant to do it some other way, like with
     * a proper abstraction for the non-portable parts. */
    
    typedef int SOCKET;
    
    #define INVALID_SOCKET  ((SOCKET)-1)
    
    /* OK, "inline" is a C99 feature, not C89, but you get the idea... */
    static inline int closesocket(int fd) { return close(fd); }
    #endif
    

    然后,一旦你做了这样的事情,你可以针对出现在两个操作系统中的函数进行编码,在适当的地方使用这些包装器。

    【讨论】:

    • 这是否意味着我无法移植到 Linux? API 与 Linux 方式完全不同吗?
    • @Rosarch 我已更新我的答案以反映您的一些问题。
    • 与其用#ifdefs 乱扔代码,不如简单地用函数包装WinSock,为其提供与中途POSIX 兼容的接口...
    • @R.. - 嗯,这几乎就是我试图说明的内容,但是 ifdef 可以限制在标题中。我不认为在偏僻的标头中有一个 ifdef 是“垃圾”,但无论如何我的回答是为了说明差异以及如何弥合它们,不一定是为了提供一个最终实施和最终风格选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    相关资源
    最近更新 更多