2010-02-23 37 views
3

我是新來的C89,並嘗試做一些socket編程:Windows上的C89:getaddrinfo()?

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?

回答

6

在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等於指針的大小。儘管Microsoft有一個名爲INVALID_SOCKET的宏來隱藏這個錯誤,但您仍然可以使用與-1進行比較來發現錯誤。

  • 對於諸如設置非阻塞標誌之類的事情,您將使用ioctlsocket()而不是fcntl()

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

至於如果您開始編寫Winsock代碼,是否會失去Linux代碼的可移植性...如果您不小心,那麼是的。但是,你可以寫,試圖彌合使用#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 

然後,一旦你這樣做,你可以對其中同時出現在OS的功能代碼,適當時使用這些包裝紙。

+0

這是否意味着我將無法移植到Linux? API與Linux的方式完全不同嗎? – 2010-02-23 02:22:29

+0

@Rosarch我已經更新了我的答案,以反映你的一些問題。 – asveikau 2010-02-23 02:28:00

+0

您可能會受益於這些 http://tangentsoft.net/wskfaq/articles/lame-list.html http://beej.us/guide/bgnet/ – 2010-02-23 08:03:35