2013-06-28 79 views
-1

所以我配置了Windows 8防火墙允许IPV6出站和入站连接,作为预防措施,但每当我尝试连接到要么是远程主机到我自己的机器使用环回地址(与同时运行的ipv6服务器应用程序)连接功能失败,错误10049,无论我选择哪个端口。这是网络配置问题吗? IP4工作得很好。IPV6连接错误10049(A-GAIN!)

#include "stdafx.h" 
#include <iostream> 
#include <iostream> 
#include <string> 
#include <stdlib.h> 


#ifndef UNICODE 
#define UNICODE 
#endif 

#define WIN32_LEAN_AND_MEAN 






#include <winsock2.h> 
#include <WS2tcpip.h> 
#include <ws2ipdef.h> 
#include <iphlpapi.h> 
#include <IPTypes.h> 


#pragma comment(lib, "ws2_32.lib") 
#pragma comment(lib,"iphlpapi.lib") 



using namespace std; 


static int MAXPENDING = 5; 

void set_interface(SOCKET s, DWORD Index); 






int main(int argc,char* argv[]) 
{ 

    WSADATA wsaData; 
    int Result; 
    int optv = 1; 
    char *optval = (char*)&optv; 
    int optlen = sizeof(optval); 
    DWORD Index = 22;  
    bool connected = false; 
    string exit = "quit"; 
    string name; 
    sockaddr_in6 c_addr; 
    c_addr.sin6_family = AF_INET6; 

    char buffer[1024]; 







    Result = WSAStartup(MAKEWORD(2, 2), &wsaData); 
    if (Result != NO_ERROR) { 
     printf("WSAStartup function failed with error: %d\n", GetLastError()); 
     return 0; 
    } 





    SETUP: 

     SOCKET connector; 
     connector = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); 
     if (connector == INVALID_SOCKET) { 
      wprintf(L"socket function failed with error: %ld\n", WSAGetLastError()); 
      closesocket(connector); 
      return 1; 
     } 









     cout << "Enter host name(URL): "; 
     cin >> name; 
     cout << endl; 



     char *hostname = const_cast<char*>(name.c_str()); 

     if(inet_pton(AF_INET6,hostname,&c_addr.sin6_addr)<0){ 
      printf("InetPton() function failed with error: %d/n",GetLastError()); 
      closesocket(connector); 
      return 1; 
     } 





     string p; 
     char *hostport; 
     int p0rt; 
     cout << "Enter the port number you wish to connect on: " ; 
     cin >> p; 
     cout << endl; 
     hostport = const_cast<char*>(p.c_str()); 
     p0rt = atoi(hostport); 

     if(!(0 < p0rt && p0rt < 65,536)){ 
      cout << "Error: port number must be greater than 0 and less than 65,536. " << endl; 
      cout << endl; 
      cout << "Re-enter the port number you wish to connect on: " ; 
      cin >> p; 
      cout << endl; 
      hostport = const_cast<char*>(p.c_str()); 
      p0rt = atoi(hostport); 

     }else{ 
      c_addr.sin6_port = htons(p0rt); 
     } 








    if(connect(connector,(sockaddr*)&c_addr,sizeof(c_addr))<0){ 
      printf("Connect failed with error: %d\n",GetLastError()); 
      string cmd; 
      cout << endl; 
      cout <<"Try again? Type 'y' to reattempt connection or type any other key to exit: "; 
      cin >> cmd; 
      cout << endl; 
      if(cmd=="y"){ 

       goto SETUP; 
      }else { 
       goto QUIT; 
      } 


    }else{ 
     connected = true; 
     cout << "Connected to host " << hostname << " on port " << c_addr.sin6_port << endl; 
     cout << "Type 'quit' to exit the program " << endl; 
    } 

    while(connected==true){ 

     int nbr = 0; 


     cout << endl; 
     cout << ">"; 
     scanf("%s",buffer); 
     cout << endl; 

     string str(buffer); 

     if(str==exit){ 

      connected = false; 
      goto QUIT; 
     } 




     long nbs = send(connector,buffer,sizeof(buffer),0); 
     if(nbs < 0){ 
      printf("send() failed", GetLastError()); 
      goto QUIT; 
     } 

     while(nbr < nbs){ 
      nbr = recv(connector,buffer,sizeof(buffer),0); 
      if(nbr < 0){ 
       printf("recv() failed", GetLastError()); 
       goto QUIT; 

      }else if(nbr==0){ 
       printf("recv() failed: connection closed prematurely", GetLastError()); 
       goto QUIT;    
      }else if(nbr > 0){ 
       cout << endl; 
       cout << ">> "; 
       printf(buffer); 
       cout << endl; 
      } 

     } 



    } 


    QUIT: 

     if (closesocket(connector) == SOCKET_ERROR) { 
      printf("closesocket function failed with error: %ld\n", GetLastError()); 
      WSACleanup(); 
      return 1; 
     } 


    WSACleanup(); 

    return 0; 




}; 


void set_interface(SOCKET s, DWORD Index){ 




     MIB_IF_ROW2 T2; 
     NET_LUID ID; 
     DWORD ptbuflen = (DWORD)sizeof(T2); 


     ConvertInterfaceIndexToLuid(Index,&ID); 
     T2.InterfaceLuid = ID; 
     GetIfEntry2(&T2); 



     if(WSAIoctl(s,SIO_ASSOCIATE_HANDLE,&T2,ptbuflen,NULL,0,0,NULL,NULL)>0){ 
      printf("WSAIoctl() function failed with error: %d\n", GetLastError()); 
      closesocket(s); 


     } 

     if(WSAIoctl(s,SIO_TRANSLATE_HANDLE,&T2,ptbuflen,NULL,0,0,NULL,NULL)>0){ 
      printf("WSAIoctl() function failed with error: %d\n", GetLastError()); 
      closesocket(s); 


     } 

}; 
+0

可能重复的[bind()失败与Windows套接字错误10049](http://stackoverflow.com/questions/14366048/bind-fails-with-windows-socket-error-10049) –

回答

1

您需要将您未使用的部分置零。先将零件清零,然后填写你需要的零件。

如果用户第一次无法输入有效的端口,则不会验证第二次输入的新端口,而且您也没有将该第二端口值分配给。您应该循环进行验证,然后将最终接受的值分配给。

如果您应该使用getaddrinfo()代替,则正在使用inet_pton()inet_pton()仅将IP地址字符串转换为其二进制格式。它不会将主机名解析为IP。 getaddrinfo()代替该分辨率,并且还支持转换IP地址字符串(指定参数hints中的AI_NUMERICHOST标志以获得该行为)。

+0

谢谢。这似乎工作。但是sockaddr_in6结构呢?我需要指定scopeID,以便知道接口的用途。 –

+0

不,您不需要指定范围ID。如果你想使用特定的接口进行连接,那么在调用connect()之前,将套接字bind()到该接口的本地IP地址。 –

+0

我能够使用WSAIoctl()函数指定连接接口。感谢你的帮助。 FTR:我清理了sockaddr_in6结构,并使用了getaddrinfo()的addrinfo结构,这就是诀窍。 –