C89: getaddrinfo () в Windows? - PullRequest
       31

C89: getaddrinfo () в Windows?

3 голосов
/ 23 февраля 2010

Я новичок в 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:

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

Что мне делать? Значит ли это, что у меня не будет переносимости в Linux?

1 Ответ

6 голосов
/ 23 февраля 2010

В 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().

Что касается того, потеряете ли вы переносимость кода Linux, если начнете писать код для Winsock ... Если вы не будете осторожны, тогда да. Но вы можете написать код, который пытается заполнить пробелы, используя #ifdef s ..

Например:

#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

Затем, когда вы сделаете что-то подобное, вы можете кодировать функции, которые появляются в обеих ОС, используя эти оболочки, где это уместно.

...