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?

4

1 回答 1

6

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

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

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

Winsock 和 POSIX 之间的其他一些差异包括:

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

  • close()现在称为closesocket().

  • 不是将套接字作为 传递,而是有一个等于指针大小的inttypedef 。SOCKET您仍然可以使用比较来-1判断错误,尽管 Microsoft 有一个宏调用INVALID_SOCKET来隐藏它。

  • 对于设置非阻塞标志之类的事情,您将使用ioctlsocket()而不是fcntl().

  • 您必须使用send()andrecv()而不是write()and 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

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

于 2010-02-23T02:14:28.003 回答