C89:在Windows上使用getaddrinfo()函数?

3

我是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上移植?

1个回答

6
在Windows上,不需要你提到的那些包含文件,只需使用以下内容即可:
#include <winsock2.h>
#include <windows.h>

你还需要链接ws2_32.lib库。虽然这样做有点丑陋,但对于VC++来说,你可以通过以下方式实现:#pragma comment(lib, "ws2_32.lib") Winsock和POSIX之间的一些其他区别包括:
  • 在使用任何套接字函数之前,您必须调用WSAStartup()

  • 现在关闭套接字的函数名是closesocket()而不是close()

  • 除了将套接字作为int传递外,还有一个typedef SOCKET等于指针的大小。您仍然可以使用-1进行错误比较,尽管Microsoft有一个名为INVALID_SOCKET的宏来隐藏此问题。

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

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

至于你是否会因为开始编写Winsock而失去Linux代码的可移植性...如果你不小心,那么是的。但是,您可以编写尝试使用#ifdef来弥合差距的代码。
例如:
#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的方式完全不同吗? - Nick Heiner
@Rosarch 我已经更新了我的答案以反映你的一些问题。 - asveikau
你可能会从这些中受益http://tangentsoft.net/wskfaq/articles/lame-list.htmlhttp://beej.us/guide/bgnet/ - Arthur Kalliokoski
与其在代码中满是 #ifdef,不如使用函数将 WinSock 包装起来,使其具有半 POSIX 兼容接口。 - R.. GitHub STOP HELPING ICE
@R.. - 嗯,这基本上就是我试图说明的内容,但是使用ifdef可以限制在头文件中。我认为在一个不起眼的头文件中有一个单一的ifdef并不会造成“垃圾代码”,但无论如何,我的回答旨在说明差异以及如何弥合它们,而不一定提供最终实现和最终风格选择。 - asveikau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接