2014-12-31 32 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) 
     { 
      ... 
     } 
    } 

    ... 
}