升級支援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 =
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
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");
}