0

每当我使用 IPV6 时,我都会不断收到 InetPton 函数的错误代码。我检查了网络/IP 配置并有一个活动的隧道本地连接(具有完整的 ipv6 地址)。但是每次我输入一个 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;



};
4

2 回答 2

1

API 采用原始地址而InetPton不是套接字地址。

根据Microsoft 示例替换struct sockaddr_in6为。IN6_ADDR

套接字地址结构包括原始地址:

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;
};
于 2013-06-14T00:01:46.753 回答
1

您已将指向 C++ 字符串的指针hostname作为第二个参数传递给InetPton并尝试将其类型转换为PCTSTR. 但InetPton需要一个指向以 NULL 结尾的 C 字符串的指针

要解决此问题,请改为传入C 字符串:

if(InetPton(AF_INET6, hostname.c_str(), &caddr.sin6_addr.s6_addr) < 1){
于 2013-06-14T18:17:55.660 回答