С89:getaddrinfo() в Windows?
Вопрос
Я новичок в 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?
Решение
В Windows вместо упомянутых вами включений должно быть достаточно:
#include <winsock2.h>
#include <windows.h>
Вам также потребуется ссылка на ws2_32.lib
.Делать это таким образом некрасиво, но для VC++ это можно сделать с помощью: #pragma comment(lib, "ws2_32.lib")
Некоторые другие различия между Winsock и POSIX включают в себя:
Вам придется позвонить
WSAStartup()
перед использованием каких-либо функций сокета.close()
теперь называетсяclosesocket()
.Вместо передачи сокетов как
int
, есть определение типаSOCKET
равен размеру указателя.Вы все еще можете использовать сравнения с-1
за ошибку, хотя у Microsoft есть макрос под названиемINVALID_SOCKET
чтобы скрыть это.Для таких вещей, как установка неблокирующих флагов, вы будете использовать
ioctlsocket()
вместоfcntl()
.Вам придется использовать
send()
иrecv()
вместоwrite()
иread()
.
Что касается того, потеряете ли вы переносимость кода Linux, если начнете писать код для Winsock...Если не быть осторожным, то да.Но вы можете написать код, который попытается устранить пробелы, используя #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
Затем, сделав что-то подобное, вы можете кодировать функции, которые появляются в обеих ОС, используя эти оболочки там, где это необходимо.