应用程序在IPv6网络上进行审核。请确保您的应用支持IPv6网络,因为需要IPv6兼容性

时间:2016-06-13 22:08:07

标签: ios iphone sockets networking ipv6

在过去的几天里,我收到了Apple对我的应用程序的以下拒绝。我的应用程序与UDP通信,远程服务器始终是IPv4。我使用过BSD套接字。请指导我如何解决这个问题。

我曾尝试使用IPv4网络创建NAT64热点,但我无法将任何数据包发送到服务器。此外,我们现在没有IPv6可用。

来自Apple:

  

2.2详细信息

     

我们发现,在运行iOS 9.3.2的iPad上以及在Wi-Fi和蜂窝网络上运行iOS 9.3.2的iPhone上,您的应用中存在一个或多个错误。

     

具体而言,在审核期间,我们无法绕过“初始化”页面。我们在等待加载应用时遇到错误。我们附上了一个截图供您参考。

     

后续步骤

     

请在设备上运行您的应用以识别问题,然后修改并重新提交您的应用以供审核。

     

在IPv6网络上审核应用。请确保您的应用支持IPv6网络,因为需要IPv6兼容性。

     

有关支持IPv6网络的其他信息,请参阅支持iPv6 DNS64 / NAT64网络。

源代码Bellow:

UdpSocketManager.h>>

#ifndef UDP_SOCKET_MANAGER_H__
#define UDP_SOCKET_MANAGER_H__

#import "TInetAddr.h"

class UdpSocketManager
{
public:
    UdpSocketManager();
    ~UdpSocketManager();

    void getLocalAddress();
    void initializeSocket();
    void start();
    void stop();

    void sendSignal(int p_type, TInetAddr *p_destAddress, unsigned char *p_data, int p_length); 
    void receiveSignal();

    int localPort;    
    int signalingSocket;
    int signalSocketRecvLength;
    int socketFamily;

    int isIPV4Available;
    int isIPV6Available;

    char wifiIP[INET_ADDRSTRLEN];
    char cellularIP[INET_ADDRSTRLEN];

    char wifiIP_v6[INET6_ADDRSTRLEN];
    char cellularIP_v6[INET6_ADDRSTRLEN];    

    long returnLength;
    struct sockaddr_in remoteAddrForRecv;

    struct sockaddr_in  srcAddrV4;
    struct sockaddr_in6 srcAddrV6;    

    struct sockaddr_in  sendAddr4;
    struct sockaddr_in6 sendAddr6;

    bool running;
    pthread_t thread;
};

#endif

UdpSocketManager.m>>

#include <string.h>
#include <pthread.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#include "UdpSocketManager.h"
#import <Foundation/Foundation.h>

unsigned int ipAddressToUnsignedInt(char *ipAddress)
{
    unsigned int ipAddressLongValue = 0L;
    int byteSegment = 0;

    for(int i = 0; i < strlen(ipAddress); i++)
    {
        char ch = ipAddress[i];
        if(ch == '.')
        {
            ipAddressLongValue <<= 8;
            ipAddressLongValue |= byteSegment;
            byteSegment = 0;
        }
        else
        {
            byteSegment = byteSegment * 10 + (ch - 48);
        }
    }

    ipAddressLongValue <<= 8;
    ipAddressLongValue |= byteSegment;
    return ipAddressLongValue;
}

int custom_random(int max=65535)
{
    int randomValue;
    randomValue = arc4random_uniform(65535)%max;
    return randomValue;
}

int custom_random(int min, int max)
{
    int randomValue;
    randomValue = arc4random_uniform(max);
    if(randomValue<min)
        randomValue=(min+custom_random(max-min));
    return randomValue;
}



void* runUdpSocketManager(void *objRef)
{
    UdpSocketManager *THIS = (UdpSocketManager *) objRef;
    THIS->running=true;

    while (THIS->running) 
    {
        THIS->receiveSignal();
    }

    pthread_exit(NULL);
    return 0;
}


UdpSocketManager::UdpSocketManager()
{
    socketFamily=AF_INET;
    signalingSocket=-1;
    running=false;
    initializeSocket();
}

UdpSocketManager::~UdpSocketManager()
{

}

void UdpSocketManager::getLocalAddress()
{
    //Read local address
    getLocalAddress();

    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success=0;

    isIPV4Available=FALSE;
    isIPV6Available=FALSE;
    success = getifaddrs(&interfaces);

    if (success == 0)
    {
        // Loop through linked list of interfaces
        temp_addr = interfaces;
        while(temp_addr != NULL)
        {
            if(temp_addr->ifa_addr->sa_family==AF_INET)
            {
                if([[NSString stringWithUTF8String:temp_addr->ifa_name] hasPrefix:@"en"])
                {
                    isIPV4Available=TRUE;
                    strcpy(wifiIP, inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr));
                    printf("IP Address: %s\n",inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr));
                }
                else if([[NSString stringWithUTF8String:temp_addr->ifa_name] hasPrefix:@"pdp_ip0"])
                {
                    isIPV4Available=TRUE;
                    strcpy(cellularIP, inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr));
                    printf("IP Address: %s\n",inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr));
                }
            }
            else if(temp_addr->ifa_addr->sa_family==AF_INET6)
            {
                if([[NSString stringWithUTF8String:temp_addr->ifa_name] hasPrefix:@"en"])
                {
                    isIPV6Available=TRUE;
                    inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)temp_addr->ifa_addr)->sin6_addr), (char*)wifiIP_v6, INET6_ADDRSTRLEN);
                    printf("Interface: %s IPV6: %s\n",temp_addr->ifa_name,wifiIP_v6);
                }
                else if([[NSString stringWithUTF8String:temp_addr->ifa_name] hasPrefix:@"pdp_ip0"])
                {
                    isIPV6Available=TRUE;
                    inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)temp_addr->ifa_addr)->sin6_addr), (char*)cellularIP_v6, INET6_ADDRSTRLEN);
                    printf("Interface: %s IPV6: %s\n",temp_addr->ifa_name,cellularIP_v6);
                }
            }
            temp_addr = temp_addr->ifa_next;
        }
    }
    freeifaddrs(interfaces);
}

void UdpSocketManager::initializeSocket()
{
    if(signalingSocket!=-1)
        close(signalingSocket);

    if (isIPV4Available)
    {
        if((signalingSocket=socket(AF_INET, SOCK_DGRAM, 0))==-1)
        {
            NSLog(@"Unable to create signaling socket of AF_INET");
        }
        else
        {
            socketFamily=AF_INET;
            NSLog(@"Socket created successfully. [AF_INET]");
        }
    }
    else if(!isIPV4Available && isIPV6Available)
    {
        if((signalingSocket=socket(AF_INET6, SOCK_DGRAM, 0))==-1)
        {
            NSLog(@"Unable to create signaling socket of AF_INET6");
        }
        else
        {
            socketFamily=AF_INET6;
            NSLog(@"Socket created successfully. [AF_INET6]");
        }
    }
    else
    {
        if((signalingSocket=socket(AF_INET, SOCK_DGRAM, 0))==-1)
        {
            NSLog(@"Unable to create signaling socket of AF_INET");
        }
        else
        {
            socketFamily=AF_INET;
            NSLog(@"Socket created successfully. [AF_INET]");
        }
    }

    int count=0;
    while(true)
    {
        count++;
        if(socketFamily==AF_INET)
        {
            srcAddrV4.sin_len = sizeof(srcAddrV4);
            srcAddrV4.sin_family = socketFamily;
            srcAddrV4.sin_addr.s_addr = INADDR_ANY;
            srcAddrV4.sin_port = htons(localPort);

            if (bind(signalingSocket, (struct sockaddr *) &srcAddrV4, sizeof(srcAddrV4)) < 0)
            {
                NSLog(@"[AF_INET] ERROR occured creating signaling port at attempt (%d) Port: %d", count, localPort);
                localPort=(int)custom_random(1024, 65535);
            }
            else
            {
                int on=1;
                setsockopt(signalingSocket, SOL_SOCKET, SO_NOSIGPIPE, (void *)&on, sizeof(on));
                setsockopt(signalingSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));

                NSLog(@"[AF_INET] SignalingSocket Created Successfully at attempt (%d) Port: %d\n", count, localPort);
                break;
            }
        }
        else
        {
            srcAddrV6.sin6_len = sizeof(srcAddrV6);
            srcAddrV6.sin6_family = socketFamily;
            srcAddrV6.sin6_addr = in6addr_any;
            srcAddrV6.sin6_port = htons(localPort);

            if (bind(signalingSocket, (struct sockaddr *) &srcAddrV6, sizeof(srcAddrV6)) < 0)
            {
                NSLog(@"[AF_INET] ERROR occured creating signaling port at attempt (%d) Port: %d", count, localPort);
                localPort=(int)custom_random(1024, 65535);
            }
            else
            {
                int on=1;
                setsockopt(signalingSocket, SOL_SOCKET, SO_NOSIGPIPE, (void *)&on, sizeof(on));
                setsockopt(signalingSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
                NSLog(@"[AF_INET6] SignalingSocket Created Successfully at attempt (%d) Port: %d\n", count, localPort);
                break;
            }
        }
    }
}

void UdpSocketManager::start()
{
    pthread_create(&thread, NULL, runUdpSocketManager, (void *) this);
}

void UdpSocketManager::stop()
{
    running=false;
}

void UdpSocketManager::receiveSignal()
{
    int port;
    char ipAddress[16];

    socklen_t fromlen;
    unsigned char udpSignalRecvBuffer[1600];

    fromlen = sizeof(remoteAddrForRecv);
    signalSocketRecvLength = (int)recvfrom(signalingSocket, (char *)udpSignalRecvBuffer,1600,0,(struct sockaddr *)&remoteAddrForRecv,&fromlen);

    if(signalSocketRecvLength>0)
    {
        strcpy(ipAddress, inet_ntoa(remoteAddrForRecv.sin_addr));
        port = ntohs(remoteAddrForRecv.sin_port);
        NSLog(@"RECEIVED %d bytes from %s:%d", signalSocketRecvLength, ipAddress, port);
    }
    else
    {
        usleep(10000);// 10 ms
    }
}


void UdpSocketManager::sendSignal(int p_type, TInetAddr *p_destAddress, unsigned char *p_data, int p_length)
{
    if(socketFamily==AF_INET6)
    {
        // Convert IPv4 address to IPv4-mapped-into-IPv6 address.        
        sendAddr6.sin6_family = AF_INET6;
        sendAddr6.sin6_port = p_destAddress->m_port;

        sendAddr6.sin6_addr.__u6_addr.__u6_addr32[0] = 0;
        sendAddr6.sin6_addr.__u6_addr.__u6_addr32[1] = 0;
        sendAddr6.sin6_addr.__u6_addr.__u6_addr32[2] = htonl(0xffff);
        sendAddr6.sin6_addr.__u6_addr.__u6_addr32[3] = ntohl(ipAddressToUnsignedInt(p_destAddress->m_address));

        sendAddr6.sin6_addr.__u6_addr.__u6_addr16[4] = 0;
        sendAddr6.sin6_addr.__u6_addr.__u6_addr16[5] = 0xffff;

        char ipV6Address[INET6_ADDRSTRLEN];
        inet_ntop(AF_INET6, &sendAddr6.sin6_addr, ipV6Address, INET6_ADDRSTRLEN);
        NSLog(@"ipV6Address: %s\n", ipV6Address);

        sendAddr6.sin6_flowinfo = 0;
        sendAddr6.sin6_scope_id = 0;
    }
    else
    {
        sendAddr4.sin_family = AF_INET;
        sendAddr4.sin_port   = htons(p_destAddress->m_port);

        if(inet_aton((char *) p_destAddress->m_address, &sendAddr4.sin_addr)==0)
        {
            NSLog(@"signal message - inet_aton() failed, %s", p_destAddress->m_address);
        }
    }


    if(socketFamily==AF_INET)
        returnLength=sendto(signalingSocket, p_data, p_length, 0, (struct sockaddr *)&sendAddr4, sizeof(sendAddr4));
    else
        returnLength=sendto(signalingSocket, p_data, p_length, 0, (struct sockaddr *)&sendAddr6, sizeof(sendAddr6));

    NSLog(@"SENT %ld bytes to %s:%d\n", returnLength,p_destAddress->m_address,p_destAddress->m_port);
}

3 个答案:

答案 0 :(得分:3)

我不认为您的“将IPv4地址转换为IPv4映射到IPv6地址”是正确的。您应该使用您要连接的事物的字符串(可以是主机名或IPv4地址文字)来调用getaddrinfo(),而不是尝试自己构建地址,它将返回给您一个列表sockaddr的;你应该使用那里的第一个传递给sendto。它将为您提供适当的IP地址系列,如果您提供IPv4地址并且它是仅IPv6网络(无需进行任何测试),它将自动为您提供用于该NAT64的正确IPv6地址路由器(你无需自己解决这个问题)。 (如果您想使用NAT64 / DNS64从IPv4手动构建IPv6地址而不使用getaddrinfo(),则必须遵循RFC 7050中的复杂过程。)

此外,您在getLocalAddress()中所做的所有事情都是不必要的,并可能导致更多问题。您不需要isIPV4AvailableisIPV6Available - 您不应该在意这一点。只需在开始时创建并绑定两者 IPv4和IPv6套接字(无需关心哪个工作),每次需要发送时,都可以使用正确的sockaddr如上所述使用getaddrinfo(),然后发送到地址系列与您正在使用的sockaddr对应的套接字。当您想要接收时,请在两个套接字上调用recvfrom

答案 1 :(得分:1)

我看到您显示的代码有几个问题:

  1. UdpSocketManager在调用getLocalAddress()之前未调用initializeSocket(),因此绑定套接字始终为IPv4,而不是IPv6。在致电localPort之前,您也没有初始化initializeSocket()

  2. getLocalAddress()(如果有人调用过)调用自己,所以你有一个无限的递归循环。

  3. 在循环中使用custom_random()来挑选随机绑定端口是完全错误的,不必要的,并且可能无休止。要在配置的端口出现故障时选择随机端口,只需调用bind() 一次,并将端口设置为0.操作系统知道哪些端口可用,并为您选择可用的随机端口。您的整个initializeSocket()过于复杂,无法尝试做什么。它可以大大简化。

  4. 启用SO_REUSEADDR时,必须在调用bind()之前启用,而不是之后。另请查看SO_REUSEPORT

  5. 您的remoteAddrForRecv变量被声明为sockaddr_in,该变量仅足以容纳IPv4地址,并且如果在IPv6套接字上调用,将导致recvfrom()失败。请改用sockaddr_storage。事实上。您的所有sockaddr_insockaddr_in6变量都应替换为sockaddr_storage

  6. inet_ntoa()同样也是仅限IPv4的。请改用inet_ntop()来处理IPv4和IPv6地址。

  7. 尝试更像这样的东西:

    UdpSocketManager.h

    #ifndef UDP_SOCKET_MANAGER_H__
    #define UDP_SOCKET_MANAGER_H__
    
    #import "TInetAddr.h"
    
    class UdpSocketManager
    {
    public:
        UdpSocketManager();
        ~UdpSocketManager();
    
        void getLocalAddresses();
        void initializeSocket();
        void start();
        void stop();
    
        void sendSignal(int p_type, TInetAddr *p_destAddress, unsigned char *p_data, int p_length);    
        void receiveSignal();
    
        int localPort;    
        int signalingSocket;
        int socketFamily;
    
        int isIPV4Available;
        int isIPV6Available;
    
        char wifiIP_v4[INET_ADDRSTRLEN];
        char cellularIP_v4[INET_ADDRSTRLEN];
    
        char wifiIP_v6[INET6_ADDRSTRLEN];
        char cellularIP_v6[INET6_ADDRSTRLEN];    
    
        bool running;
        pthread_t thread;
    };
    
    #endif
    

    UdpSocketManager.m

    #include <string.h>
    #include <pthread.h>
    #include <ifaddrs.h>
    #include <arpa/inet.h>
    #include <sys/socket.h>
    
    #include "UdpSocketManager.h"
    #import <Foundation/Foundation.h>
    
    void* runUdpSocketManager(void *objRef)
    {
        UdpSocketManager *THIS = (UdpSocketManager *) objRef;
    
        while (THIS->running) 
        {
            THIS->receiveSignal();
        }
    
        pthread_exit(NULL);
        return 0;
    }
    
    UdpSocketManager::UdpSocketManager()
    {
        socketFamily = AF_INET;
        signalingSocket = -1;
        localPort = 0; // or whatever port you actual want
        srcAddrLen = 0;
        sendAddrLen = 0;
        running = false;
        initializeSocket();
    }
    
    UdpSocketManager::~UdpSocketManager()
    {
        if(signalingSocket != -1)
        {
            close(signalingSocket);
            signalingSocket = -1;
        }
    }
    
    void UdpSocketManager::getLocalAddresses()
    {
        //Read local addresses
    
        struct ifaddrs *interfaces = NULL;
        struct ifaddrs *temp_addr = NULL;
    
        isIPV4Available = FALSE;
        isIPV6Available = FALSE;
    
        memset(&wifiIP_v4, 0, sizeof(wifiIP_v4));
        memset(&cellularIP_v4, 0, sizeof(cellularIP_v4));
    
        memset(&wifiIP_v6, 0, sizeof(wifiIP_v6));
        memset(&cellularIP_v6, 0, sizeof(cellularIP_v6));
    
        if(getifaddrs(&interfaces) == 0)
        {
            // Loop through linked list of interfaces
            temp_addr = interfaces;
            while(temp_addr != NULL)
            {
                if ([[NSString stringWithUTF8String:temp_addr->ifa_name] hasPrefix:@"en"])
                {
                    if(temp_addr->ifa_addr->sa_family == AF_INET)
                    {
                        isIPV4Available = TRUE;
                        inet_ntop(AF_INET, &(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr), wifiIP_v4, sizeof(wifiIP_v4));
                        printf("Interface: %s IPv4: %s\n", temp_addr->ifa_name, wifiIP_v4);
                    }
                    else if(temp_addr->ifa_addr->sa_family == AF_INET6)
                    {
                        isIPV6Available = TRUE;
                        inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)temp_addr->ifa_addr)->sin6_addr), wifiIP_v6, sizeof(wifiIP_v6));
                        printf("Interface: %s IPv6: %s\n", temp_addr->ifa_name, wifiIP_v6);
                    }
                }
                else if([[NSString stringWithUTF8String:temp_addr->ifa_name] hasPrefix:@"pdp_ip0"])
                {
                    if(temp_addr->ifa_addr->sa_family == AF_INET)
                    {
                        isIPV4Available = TRUE;
                        inet_ntop(AF_INET, &(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr), cellularIP_v4, sizeof(cellularIP_v4));
                        printf("Interface: %s IPv6: %s\n", temp_addr->ifa_name, cellularIP_v4);
                    }
                    else if(temp_addr->ifa_addr->sa_family == AF_INET6)
                    {
                        isIPV6Available = TRUE;
                        inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)temp_addr->ifa_addr)->sin6_addr), cellularIP_v6, sizeof(cellularIP_v6));
                        printf("Interface: %s IPv6: %s\n", temp_addr->ifa_name, cellularIP_v6);
                    }
                }
                temp_addr = temp_addr->ifa_next;
            }
    
            freeifaddrs(interfaces);
        }
    }
    
    void UdpSocketManager::initializeSocket()
    {
        struct sockaddr_storage srcAddr;
        struct sockaddr_in6 *srcAddr6;
        struct sockaddr_in *srcAddr4;
        socklen_t srcAddrLen;
    
        if(signalingSocket != -1)
        {
            close(signalingSocket);
            signalingSocket = -1;
        }
    
        getLocalAddresses();
    
        if(isIPV6Available)
        {
            signalingSocket = socket(AF_INET6, SOCK_DGRAM, 0);
            if(signalingSocket == -1)
            {
                NSLog(@"Unable to create IPv6 signaling socket");
                return;
            }
    
            socketFamily = AF_INET6;
            NSLog(@"IPv6 Socket created successfully");
        }
        else
        {
            signalingSocket = socket(AF_INET, SOCK_DGRAM, 0);
            if(signalingSocket == -1)
            {
                NSLog(@"Unable to create IPv4 signaling socket");
                return;
            }
    
            socketFamily = AF_INET;
            NSLog(@"IPv4 Socket created successfully");
        }
    
        int on = 1;
        setsockopt(signalingSocket, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on));
        setsockopt(signalingSocket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
    
        if(socketFamily == AF_INET6)
        {
            on = 0;
            setsockopt(signalingSocket, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
    
            srcAddr6 = (struct sockaddr_in6 *) &srcAddr;
            srcAddrLen = sizeof(sockaddr_in6);
    
            srcAddr6->sin6_len = srcAddrLen;
            srcAddr6->sin6_family = socketFamily;
            srcAddr6->sin6_addr = in6addr_any;
            srcAddr6->sin6_port = htons(localPort);
        }
        else
        {
            srcAddr4 = (struct sockaddr_in *) &srcAddr;
            srcAddrLen = sizeof(sockaddr_in);
    
            srcAddr4->sin_len = srcAddrLen;
            srcAddr4->sin_family = socketFamily;
            srcAddr4->sin_addr.s_addr = INADDR_ANY;
            srcAddr4->sin_port = htons(localPort);
        }
    
        if (bind(signalingSocket, (struct sockaddr *) &srcAddr, srcAddrLen) < 0)
        {
            if (localPort == 0)
            {
                NSLog(@"ERROR occured binding random signaling port");
                close(signalingSocket);
                signalingSocket = -1;
                return;
            }
    
            NSLog(@"ERROR occured binding signaling port: %d", localPort);
    
            if(socketFamily == AF_INET6)
                srcAddr6->sin6_port = 0;
            else
                srcAddr4->sin_port = 0;
    
            if (bind(signalingSocket, (struct sockaddr *) &srcAddr, srcAddrLen) < 0)
            {
                NSLog(@"ERROR occured binding random signaling port");
                close(signalingSocket);
                signalingSocket = -1;
                return;
            }
    
            getsockname(signalingSocket, (struct sockaddr *) &srcAddr, &srcAddrLen);
    
            if(socketFamily == AF_INET6)
                localPort = ntohs(srcAddr6->sin6_port);
            else
                localPort = ntohs(srcAddr4->sin_port);
        }
    
        NSLog(@"SignalingSocket bound successfully on Port: %d\n", localPort);
    }
    
    void UdpSocketManager::start()
    {
        if(signalingSocket != -1)
        {
            running = true;
            pthread_create(&thread, NULL, runUdpSocketManager, this);
        }
    }
    
    void UdpSocketManager::stop()
    {
        running = false;
    }
    
    void UdpSocketManager::receiveSignal()
    {
        int port;
        char ipAddress[INET6_ADDRSTRLEN];
    
        unsigned char udpSignalRecvBuffer[1600];
        ssize_t signalRecvLength;
    
        struct sockaddr_storage remoteAddr;
        socklen_t fromlen;
    
        fromlen = sizeof(remoteAddr);
        signalRecvLength = recvfrom(signalingSocket, udpSignalRecvBuffer, sizeof(udpSignalRecvBuffer), 0, (struct sockaddr *) &remoteAddr, &fromlen);
    
        if(signalRecvLength >= 0)
        {
            if(remoteAddrForRecv.ss_family == AF_INET6)
            {
                struct sockaddr_in6 *remoteAddr6 = (struct sockaddr_in6 *) &remoteAddr;
                inet_ntop(AF_INET6, &(remoteAddr6->sin6_addr), ipAddress, sizeof(ipAddress));
                port = ntohs(remoteAddr6->sin6_port);
            }
            else
            {
                struct sockaddr_in *remoteAddr4 = (struct sockaddr_in4 *) &remoteAddr;
                inet_ntop(AF_INET, &(remoteAddr4->sin_addr), ipAddress, sizeof(ipAddress));
                port = ntohs(remoteAddr4->sin_port);
            }
    
            NSLog(@"RECEIVED %d bytes from %s:%d", signalRecvLength, ipAddress, port);
        }
        else
        {
            usleep(10000);// 10 ms
        }
    }
    
    
    void UdpSocketManager::sendSignal(int p_type, TInetAddr *p_destAddress, unsigned char *p_data, int p_length)
    {
        struct sockaddr_storage sendAddr;
        socklen_t sendAddrLen;
    
        ssize_t returnLength;
    
        char ipAddress[INET6_ADDRSTRLEN];
    
        if(socketFamily == AF_INET6)
        {
            struct sockaddr_in6 *sendAddr6 = (struct sockaddr_in6 *) &sendAddr;
            sendAddrLen = sizeof(sockaddr_in6);
    
            sendAddr6->sin6_family = AF_INET6;
            sendAddr6->sin6_port = htons(p_destAddress->m_port);
    
            // Convert IPv4 address to IPv4-mapped IPv6 address.        
            sendAddr6->sin6_addr.__u6_addr.__u6_addr32[0] = 0;
            sendAddr6->sin6_addr.__u6_addr.__u6_addr32[1] = 0;
            sendAddr6->sin6_addr.__u6_addr.__u6_addr16[4] = 0;
            sendAddr6->sin6_addr.__u6_addr.__u6_addr16[5] = 0xffff;
            sendAddr6->sin6_addr.__u6_addr.__u6_addr32[3] = inet_addr(p_destAddress->m_address);            
    
            sendAddr6->sin6_flowinfo = 0;
            sendAddr6->sin6_scope_id = 0;
    
            inet_ntop(AF_INET6, &(sendAddr6->sin6_addr), ipAddress, sizeof(ipAddress));
        }
        else
        {
            struct sockaddr_in *sendAddr4 = (struct sockaddr_in *) &sendAddr;
            sendAddrLen = sizeof(sockaddr_in);
    
            sendAddr4->sin_family = AF_INET;
            sendAddr4->sin_port = htons(p_destAddress->m_port);
    
            if(inet_aton((char *) p_destAddress->m_address, &(sendAddr4->sin_addr)) == 0)
            {
                NSLog(@"signal message - inet_aton() failed, %s", p_destAddress->m_address);
                return;
            }
    
            inet_ntop(AF_INET, &(sendAddr4->sin_addr), ipAddress, sizeof(ipAddress));
        }
    
        returnLength = sendto(signalingSocket, p_data, p_length, 0, (struct sockaddr *) &sendAddr, sendAddrLen);
        if(returnLength >= 0)
            NSLog(@"SENT %ld bytes to %s:%d\n", returnLength, ipAddress, p_destAddress->m_port);
    }
    

答案 2 :(得分:0)

AFNetworking在IPv6和IPv4中实现可达性的解决方案

更改类 AFNetworkReachabilityManager

中的以下代码
 + (instancetype)sharedManager {
    static AFNetworkReachabilityManager *_sharedManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        struct sockaddr_in6 address;
        bzero(&address, sizeof(address));
        address.sin6_len = sizeof(address);
        address.sin6_family = AF_INET6;
        _sharedManager = [self managerForAddress:&address];
    });
    return _sharedManager;
}