2013-06-13 2 views
0

Je continue d'obtenir le code d'erreur pour la fonction InetPton chaque fois que j'utilise IPV6. J'ai vérifié les configurations de réseau/ip et ai une connexion de zone locale de tunnel active (avec une adresse ipv6 complète). Mais chaque fois que j'entre une adresse ipv6, il s'arrête à la fonction de commande d'octets donnant l'erreur # 10022 (option de socket défectueuse). Voici le code:Erreur winsock IPV6 10022

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

#ifndef UNICODE 
#define UNICODE 
#endif 

#define WIN32_LEAN_AND_MEAN 

#include <WinSock2.h> 
#include <WS2tcpip.h> 
#include <WS2spi.h> 
#include <ws2ipdef.h> 
#include <mswsock.h> 
#include "ws2isatap.h" 






#pragma comment(lib, "ws2_32.lib") 
#pragma comment(lib, "MsWSock.lib") 
#pragma comment(lib, "Kernel32.lib") 



#define SCTP_EOF   0x0100  /* Start a shutdown procedures */ 
#define SCTP_ABORT  0x0200  /* Send an ABORT to peer */ 
#define SCTP_UNORDERED 0x0400  /* Message is un-ordered */ 
#define SCTP_ADDR_OVER 0x0800  /* Override the primary-address */ 
#define SCTP_SENDALL  0x1000  /* Send this on all associations */ 
             /* for the endpoint */ 
             /* The lower byte is an enumeration of PR-SCTP policies */ 
#define SCTP_PR_SCTP_TTL 0x0001  /* Time based PR-SCTP */ 
#define SCTP_PR_SCTP_BUF 0x0002  /* Buffer based PR-SCTP */ 
#define SCTP_PR_SCTP_RTX 0x0003  /* Number of retransmissions based PR-SCTP */ 



using namespace std; 
using namespace System; 

static int LISTENQ = 5; 



#define PLU 10 /* for peer-to-peer apps */ 
#define PLER 20 /* Same as unrestricted, except for Teredo */ 
#define PLR  30 /* for Intranet apps  */ 



#ifndef _C_HOST_INFO_ 
#define _C_HOST_INFO_ 
struct c_host_info{ 

    char*     Hname; 
    int     Hport; 
    sockaddr_in6   c_addr; 
    char     *recvbuf; 
    char     *sendbuf; 
    int     bytesrcvd; 
    int     bytessent; 
}; 
#endif 


SOCKET setup(c_host_info H); 
int main(int argc,char* argv[]) 
{ 

    int iResult; 
    bool connected = false; 
    string exit = "quit"; 
    c_host_info hinfo; 




    memset(&hinfo,0,sizeof(hinfo)); 



    SETUP: 

     SOCKET connector = setup(hinfo); 


    if(connector==0){ 
     string input; 
     cout << "Socket() failed. Try again? Enter 'y' to try again or anything else to quit : "; 
     cin >> input; 
     if(input=="y"){ 
      goto SETUP; 
     }else { 
      goto QUIT; 
     } 
    } 




    if(connect(connector,(sockaddr*)&hinfo.c_addr,sizeof(hinfo.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"){ 
       closesocket(connector); 
       goto SETUP; 
      }else { 
       closesocket(connector); 
       goto QUIT; 
      } 


    }else{ 
     connected = true; 
     cout << "Connected to host " << hinfo.Hname << " on port " << hinfo.Hport << endl; 
     cout << "Type 'quit' to exit the program " << endl; 
    } 


    while(connected==true){ 



     cout << endl; 
     cout << ">"; 
     scanf("%s",hinfo.sendbuf); 
     cout << endl; 

     string str(hinfo.sendbuf); 


     if(str==exit){ 
      closesocket(connector); 
      connected = false;   
      goto QUIT; 
     } 





     hinfo.bytesrcvd = recv(connector,hinfo.recvbuf,sizeof(hinfo.recvbuf),0); 

     if(hinfo.bytesrcvd==0){ 

      printf(hinfo.Hname, ": remote client disconnected"); 
      closesocket(connector); 
      connected = false; 
      goto QUIT; 

     }else if (hinfo.bytesrcvd < 0){ 
      printf("Recv() function failed with error: ",GetLastError()); 
      closesocket(connector); 
      connected = false; 
      goto QUIT; 

     }else{ 

      string str(hinfo.recvbuf); 
      cout << "RemoteClient >> " << str << endl; 
      cout << endl; 
     } 




     iResult = send(connector,hinfo.sendbuf,sizeof(hinfo.sendbuf),0); 

     if(iResult < 0){ 
      printf("Send() failed with error: ",GetLastError()); 
      closesocket(connector); 
      connected = false; 
      goto QUIT; 

     }else{ 
      string str(hinfo.sendbuf); 
      cout << "LocalClient >> " << str << endl; 
      cout << endl;  

     } 



    } 






    QUIT: 


     WSACleanup(); 

     return 0; 





}; 

SOCKET setup(c_host_info H){ 

    WSADATA wsaData; 
    int result = 0; 
    u_long imode = 1; 
    int optv = PLU; 
    char *optval = (char*)&optv; 
    char *Imode = (char*)&imode; 
    int optlen = sizeof(optval); 
    H.recvbuf = new char[1024]; 
    H.sendbuf = new char[1024]; 





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





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






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






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

    if(!(0 < port && port < 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 >> portn; 
     cout << endl; 
     hostport = const_cast<char*>(portn.c_str()); 
     port = atoi(hostport); 

    }else{ 
     H.Hport = port; 
    } 


    sockaddr_in6 caddr; 



    caddr.sin6_family = AF_INET6; 
    caddr.sin6_port = htons(port); 

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

    memcpy(&H.c_addr,&caddr,sizeof(caddr)); 



    return s; 



}; 

Répondre

1

L'API InetPton prend les adresses brutes et non les adresses de socket.

Remplacez struct sockaddr_in6 par IN6_ADDR conformément au Microsoft example.

La structure d'adresse de socket comprend l'adresse brute:

typedef struct sockaddr_in { 
#if(_WIN32_WINNT < 0x0600) 
    short sin_family;  
#else //(_WIN32_WINNT < 0x0600) 
    ADDRESS_FAMILY sin_family; 
#endif //(_WIN32_WINNT < 0x0600) 
    USHORT sin_port; 
    IN_ADDR sin_addr; 
    CHAR sin_zero[8]; 
} SOCKADDR_IN, *PSOCKADDR_IN; 

struct sockaddr_in6 { 
     short sin6_family; 
     u_short sin6_port; 
     u_long sin6_flowinfo; 
     struct in6_addr sin6_addr; 
     u_long sin6_scope_id; 
}; 
+0

Steve-o, j'ai essayé, mais je reçois toujours l'erreur 10022 connerie de la fonction InetPton! –

1

Vous avez passé un pointeur vers une chaîne C++ hostname comme second argument à InetPton et a tenté de cataloguée à PCTSTR. Mais InetPton expects a pointer to a NULL-terminated C string.

Pour résoudre le problème, passer dans un lieu C string:

if(InetPton(AF_INET6, hostname.c_str(), &caddr.sin6_addr.s6_addr) < 1){