BYTE CClientSocket::ConnectIpv6(DWORD wdszServerIP, WORD wPort)
{
if ((wdszServerIP==0)||(wPort==0)) return CONNECT_RET_EXCEPTION;
in_addr addr;
addr.s_addr = wdszServerIP;
char * pszServerIP = inet_ntoa(addr);
#if( CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
try
{
m_UIMsgQueue.StartQueue();
m_bTryConnect = true;
//效验状态
if (m_hSocket != INVALID_SOCKET) throw CON_ERR_SOCKET_EXISTS;//throw ("连接 SOCKET 句柄已经存在");
if (m_cbSocketStatus != SOCKET_STATUS_IDLE) throw CON_ERR_STATUS_IDEL;//throw ("连接状态不是等待连接状态");
//设置参数
m_wRecvSize = 0;
m_cbSendRound = 0;
m_cbRecvRound = 0;
m_dwSendXorKey = 0;
m_dwRecvXorKey = 0;
m_dwSendTickCount = GetTickCount() / 1000L;
m_dwRecvTickCount = GetTickCount() / 1000L;
//建立 SOCKET
m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_hSocket == INVALID_SOCKET) throw CON_ERR_SOCKET_CREATE;//throw ("SOCKET 创建失败");
//填写服务器地址
m_wSocketID = m_hSocket;
struct sockaddr_in *socketaddr_ipv4;
struct sockaddr_in6 *socketaddr_ipv6;
struct addrinfo *answer, hint, *curr;
char ipstr[128];
memset(&hint, 0, sizeof(hint));
hint.ai_family = AF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
int ret = getaddrinfo(pszServerIP, NULL, &hint, &answer);
if (ret != 0) {
CCLOG("getaddrinfo error!!");
return false;
}
//设置变量
m_cbSocketStatus = SOCKET_STATUS_WAIT;
WSASetLastError(0);
int nFlags;
for (curr = answer; curr != NULL; curr = curr->ai_next) {
m_hSocket = socket(curr->ai_family, curr->ai_socktype, curr->ai_protocol);
if ((int)m_hSocket < 0) continue;
//////////////////////////////////////////////////////////////////////////////
nFlags = fcntl(m_hSocket, F_GETFL, 0);
fcntl(m_hSocket, F_SETFL, nFlags | O_NONBLOCK);
///////////////////////////////////////////////////////////////////////////////
switch (curr->ai_family) {
case AF_UNSPEC:
break;
case AF_INET:
CCLOG("SOCKET TYPE IPV4");
socketaddr_ipv4 = reinterpret_cast<struct sockaddr_in *>(curr->ai_addr);
socketaddr_ipv4->sin_port = htons(wPort);
::connect(m_hSocket, (struct sockaddr *)socketaddr_ipv4, curr->ai_addrlen);
inet_ntop(AF_INET, &socketaddr_ipv4->sin_addr, ipstr, sizeof(ipstr));
break;
case AF_INET6:
CCLOG("SOCKET TYPE IPV6");
socketaddr_ipv6 = reinterpret_cast<struct sockaddr_in6 *>(curr->ai_addr);
socketaddr_ipv6->sin6_port = htons(wPort);
::connect(m_hSocket, (struct sockaddr *)socketaddr_ipv6, curr->ai_addrlen);
inet_ntop(AF_INET6, &socketaddr_ipv6->sin6_addr, ipstr, sizeof(ipstr));
break;
default:
break;
}
CCLOG("has connect......");
break;
}
freeaddrinfo(answer);
fd_set wset;
struct timeval timeout = { 5, 0 };
int nRetConnect = 0;
int nRetSelect = 0;
int nLastError = 0;
int error = 0;
int len = 0;
int code = 0;
FD_ZERO(&wset);
FD_SET(m_hSocket, &wset);
if ((nRetSelect = select(m_hSocket + 1, 0, &wset, 0, &timeout)) == 0)
{
WSASetLastError(ETIMEDOUT);
throw WSAGetLastError();
}
if (FD_ISSET(m_hSocket, &wset))
{
len = sizeof(error);
code = getsockopt(m_hSocket, SOL_SOCKET, SO_ERROR, (void *)&error, (socklen_t *)&len);
if (code < 0 || error)
{
WSASetLastError(error);
throw WSAGetLastError();
}
goto done;
}
else
{
throw WSAGetLastError();
}
done:
fcntl(m_hSocket, F_SETFL, nFlags & ~O_NONBLOCK); /* restore file status flags */
OnSocketNotifyConnect(CON_ERR_SUCCESS);
return CONNECT_RET_SUCCESS;
}
catch (int errorcode)
{
if (m_bTryConnect)
{
OnSocketNotifyConnect(errorcode, "");
}
return CONNECT_RET_FAILURE;
}
catch (...)
{
if (m_bTryConnect)
{
OnSocketNotifyConnect(CON_ERR_EXCEPTION, "");
}
return CONNECT_RET_EXCEPTION;
}
#endif
return CONNECT_RET_EXCEPTION;
}
网友评论