2014-12-31 31 views
0

貝婁是我用來連接到Windows中的套接字的代碼的和平。有時我沒有IP着裝,但在inetAddr有DNS名稱。可能我必須從主機名解析地址,否則有可能創建名稱爲DNS的套接字?有DNS名稱時創建套接字的最佳方法是什麼?有DNS名稱時創建套接字

commStatus communicate(const char * tx, char * rx, const int bufSize , const char * inetAddr, const int port) 
{ 
... 
     SOCKET s; 
     struct sockaddr_in server; 


     server.sin_addr.s_addr = inet_addr(inetAddr); 
     server.sin_family = AF_INET; 
     server.sin_port = htons(port); 

     if((s = socket(AF_INET , SOCK_STREAM , 0)) == INVALID_SOCKET) 
     { 

      FILELOGL("Could not create socket : " << WSAGetLastError(),Level::Error); 

     } else 
     { 
      if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0) 
      { 
       FILELOGL("connect error", Level::Error); 
       r= commStatus::COMM_NO_TRANSMIT ; 
      } else 
      { 
      ... 
      } 
     } 
... 
} 
+1

解決它,親愛莉莎。 –

+1

@MartinJames親愛的亨利,我能解決什麼問題? –

+0

@IronSavior:您是否在發佈該評論前閱讀過已提供的答案? –

回答

1

只有一種方法:解析主機名。

這裏是我的代碼,我已經修改,並沒有測試的一部分,但它應該工作:

WSADATA wsdata; 

const char * inetAddr 

addrinfo hints, *res; 

WSAStartup (MAKEWORD (2, 2), &wsdata); 

memset(&hints, 0, sizeof hints); 

hints.ai_family  = AF_UNSPEC; 
hints.ai_socktype = SOCK_STREAM; 
hints.ai_protocol = IPPROTO_TCP; 

if (getaddrinfo("someaddress.com", NULL, &hints, &res) != 0) 
    return false; 

inetAddr = inet_ntoa(((sockaddr_in *) res -> ai_addr) -> sin_addr); 
+0

如果在'AF_UNSPEC'中使用'getaddrinfo()',它可以返回IPv4或IPv6地址,所以你必須延遲調用'socket()'直到你知道要創建什麼類型的套接字,無論是「AF_INET」還是「AF_INET6」。否則,如果您先創建套接字,則必須將'hints.ai_family'設置爲與實際使用的套接字系列匹配。 –

+0

@RemyLebeau是的,這是正確的,但無論如何,在創建套接字之前必須調用'getaddrinfo',因爲他說'inetAddr'有時是ip或有時是DNS名稱,那麼它並不重要該協議是IPv4或IPv6。 – schacker22

+0

而且還因爲DNS查找可以報告多個IP,所以您必須嘗試所有這些IP直到成功。看到我的答案爲這樣做的一個例子。 –

0

您需要解析DNS名稱。爲此,請使用getaddrinfo()。請注意,DNS名稱可以解析爲多個IP,包括IPv4和IPv6,因此您必須先撥打getaddrinfo()才能知道報告了多少個IP,以及爲每個IP創建什麼類型的套接字。

例如:

commStatus communicate(const char * tx, char * rx, const int bufSize , const char * inetAddr, const int port) 
{ 
    ... 
    SOCKET s = INVALID_SOCKET; 

    struct addrinfo hint = {0}; 
    hint.ai_flags = AI_NUMERICHOST; 
    hint.ai_family = AF_UNSPEC; 
    hint.ai_socktype = SOCK_STREAM; 
    hint.ai_protocol = IPPROTO_TCP; 

    struct addrinfo *addrs = NULL; 
    int ret = getaddrinfo(inetAddr, NULL, &hint, &addrs); 
    if (ret == EAI_NONAME) 
    { 
     hint.ai_flags = 0; 
     ret = getaddrinfo(inetAddr, NULL, &hint, &addrs); 
    } 

    if (ret != 0) 
    { 
     FILELOGL("Could not resolve inetAddr: " << ret, Level::Error); 
    } 
    else 
    { 
     for (struct addrinfo *addr = addrs; addr != NULL; addr = addr->ai_next) 
     { 
      s = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); 
      if (s == INVALID_SOCKET) 
      { 
       FILELOGL("Could not create socket : " << WSAGetLastError(), Level::Error); 
       break; 
      } 

      if (connect(s, addr->ai_addr, addr->ai_addrlen) == 0) 
       break; 

      closesocket(s); 
      s = INVALID_SOCKET; 

      if (addr->ai_next == NULL) 
      { 
       FILELOGL("connect error", Level::Error); 
      } 
     } 

     freeaddrinfo(addrs); 

     if (s != INVALID_SOCKET) 
     { 
      ... 
     } 
    } 

    ... 
}