1. 程式人生 > >升級支援ipv4/ipv6後的Socket處理(cocos2dx專案蘋果稽核支援ipv6處理二)

升級支援ipv4/ipv6後的Socket處理(cocos2dx專案蘋果稽核支援ipv6處理二)

升級支援ipv4/ipv6後的Socket處理

前提條件是socket已經支援ipv4處理,需修改以下兩處:

1.建立socket時

    //解析是ipv4地址還是ipv6地址

structaddrinfo addrin;

structaddrinfo* pAddr = &addrin;

int nRet = getaddrinfo(m_sAddress.c_str(), nullptr, nullptr, &pAddr);

int _ai_family;

if(nRet != 0)

    {

freeaddrinfo(pAddr);

        _ai_family =

AF_UNSPEC;

returnfalse;

    }

    _ai_family = pAddr->ai_family;

// 建立主套接字

m_sockClient = socket(_ai_family, SOCK_STREAM, IPPROTO_TCP);

if(m_sockClient == INVALID_SOCKET)

    {

freeaddrinfo(pAddr);

closeSocket();

CCLOG("CGameSocket:初始化失敗");

returnfalse;

    }

freeaddrinfo(padder);

2.connect的時候

     std::vector<std::string> ips;

structaddrinfo hints, *pAddr;

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

     hints.ai_family = PF_UNSPEC;

     hints.ai_socktype = SOCK_STREAM;

     hints.ai_flags = AI_PASSIVE;

     hints.ai_protocol = IPPROTO_IP;

int error = getaddrinfo(m_sAddress.c_str

(), nullptr, &hints, &pAddr);

if (error != 0 )

     {

printf("getaddrinfo: %s\n", gai_strerror(error));

return;

     }

if (pAddr->ai_family == AF_INET)

     {

structsockaddr_in* ipv4 = nullptr;

char str[32] = {0};

for (auto iter = pAddr; iter != nullptr; iter = iter->ai_next)

         {

            ipv4 = (structsockaddr_in*)iter->ai_addr;

inet_ntop(AF_INET, &ipv4->sin_addr, str, 32);

             ips.push_back(str);

         }

     }

elseif(pAddr->ai_family == AF_INET6)

     {

structsockaddr_in6* ipv6 = nullptr;

char str[40] = {0};

for (auto iter = pAddr; iter != nullptr; iter = iter->ai_next)

         {

             ipv6 = (structsockaddr_in6*)iter->ai_addr;

inet_ntop(AF_INET6, &ipv6->sin6_addr, str, 40);

             ips.push_back(str);

         }

     }

int nReady;

std::vector<std::string> ipVector = ips;

if (pAddr->ai_family == AF_INET6)

     {

for (auto iter = ipVector.begin(); iter!= ipVector.end(); iter++)

         {

std::string ip = iter->c_str();

sockaddr_in6 sa = {0};

structin6_addr addr = {0};

inet_pton(pAddr->ai_family, ip.c_str(), &addr);

             sa.sin6_family = pAddr->ai_family;

             sa.sin6_port = htons(m_wPort);

             sa.sin6_addr = addr;

             nReady = ::connect(m_sockClient, (sockaddr*)&sa, sizeof(sa));

if (nReady == 0) break;

         }

     }

else

     {

std::string ip = ipVector.at(0);

sockaddr_in sa = {0};

structin_addr addr = {0};

inet_pton(pAddr->ai_family, ip.c_str(), &addr);

         sa.sin_family = pAddr->ai_family;

         sa.sin_port = htons(m_wPort);

         sa.sin_addr = addr;

         nReady = ::connect(m_sockClient, (sockaddr*)&sa, sizeof(sa));

     }

freeaddrinfo(pAddr);

if( nReady != SOCKET_ERROR )

    {

//接收執行緒

std::thread pSocketRecv(&CGameSocket::onThreadRecv, this);

        pSocketRecv.detach();

CCLOG("CTCPSocket: Connect Succeed");

    }