示例#1
0
BOOL CAsyncSocketExLayer::TriggerEvent(long lEvent, int nErrorCode, BOOL bPassThrough /*=FALSE*/ )
{
  DebugAssert(m_pOwnerSocket);
  if (m_pOwnerSocket->m_SocketData.hSocket==INVALID_SOCKET)
  {
    return FALSE;
  }

  if (!bPassThrough)
  {
    if (m_nPendingEvents & lEvent)
    {
      return TRUE;
    }

    m_nPendingEvents |= lEvent;
  }

  if (lEvent & FD_CONNECT)
  {
    DebugAssert(bPassThrough);
    if (!nErrorCode)
    {
      DebugAssert(bPassThrough && (GetLayerState()==connected || GetLayerState()==attached));
    }
    else if (nErrorCode)
    {
      SetLayerState(aborted);
      m_nCriticalError=nErrorCode;
    }
  }
  else if (lEvent & FD_CLOSE)
  {
    if (!nErrorCode)
    {
      SetLayerState(closed);
    }
    else
    {
      SetLayerState(aborted);
      m_nCriticalError = nErrorCode;
    }
  }
  DebugAssert(m_pOwnerSocket->m_pLocalAsyncSocketExThreadData);
  DebugAssert(m_pOwnerSocket->m_pLocalAsyncSocketExThreadData->m_pHelperWindow);
  DebugAssert(m_pOwnerSocket->m_SocketData.nSocketIndex!=-1);
  t_LayerNotifyMsg *pMsg=new t_LayerNotifyMsg;
  pMsg->hSocket = m_pOwnerSocket->m_SocketData.hSocket;
  pMsg->lEvent = ( lEvent % 0xffff ) + ( nErrorCode << 16);
  pMsg->pLayer=bPassThrough?m_pPrevLayer:this;
  BOOL res=PostMessage(m_pOwnerSocket->GetHelperWindowHandle(), WM_USER, (WPARAM)m_pOwnerSocket->m_SocketData.nSocketIndex, (LPARAM)pMsg);
  if (!res)
  {
    delete pMsg;
  }
  return res;
}
BOOL CAsyncSocketExLayer::ConnectNext(LPCSTR lpszHostAddress, UINT nHostPort)
{
	ASSERT( lpszHostAddress != NULL );
	ASSERT( GetLayerState() == unconnected );
	ASSERT( m_pOwnerSocket );

	BOOL res;
	if (m_pNextLayer)
		res = m_pNextLayer->Connect(lpszHostAddress, nHostPort);
	else
	{
		SOCKADDR_IN sockAddr = {0};
		sockAddr.sin_addr.s_addr = inet_addr(lpszHostAddress);
		if (sockAddr.sin_addr.s_addr == INADDR_NONE)
		{
			LPHOSTENT lphost = gethostbyname(lpszHostAddress);
			if (lphost == NULL) {
				WSASetLastError(WSAEINVAL);
				return FALSE;
			}
			sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
		}
		sockAddr.sin_family = AF_INET;
		sockAddr.sin_port = htons((u_short)nHostPort);
		res = (connect(m_pOwnerSocket->GetSocketHandle(), (SOCKADDR*)&sockAddr, sizeof(sockAddr)) != SOCKET_ERROR);
	}

	if (res || WSAGetLastError() == WSAEWOULDBLOCK)
		SetLayerState(connecting);

	return res;
}
示例#3
0
void CAsyncSocketExLayer::Init(CAsyncSocketExLayer *pPrevLayer, CAsyncSocketEx *pOwnerSocket)
{
  DebugAssert(pOwnerSocket);
  m_pPrevLayer=pPrevLayer;
  m_pOwnerSocket=pOwnerSocket;
  m_pNextLayer=0;
  SetLayerState(pOwnerSocket->GetState());
}
void CAsyncSocketExLayer::CallEvent(int nEvent, int nErrorCode)
{
	if (m_nCriticalError)
		return;
	m_nCriticalError=nErrorCode;
	switch (nEvent)
	{
	case FD_READ:
	case FD_FORCEREAD:
		if (GetLayerState()==connected)
		{
			if (nErrorCode)
				SetLayerState(aborted);
			OnReceive(nErrorCode);
		}
		break;
	case FD_WRITE:
		if (GetLayerState()==connected)
		{
			if (nErrorCode)
				SetLayerState(aborted);
			OnSend(nErrorCode);
		}
		break;
	case FD_CONNECT:
		if (GetLayerState()==connecting)
		{
			if (!nErrorCode)
				SetLayerState(connected);
			else
				SetLayerState(aborted);
			OnConnect(nErrorCode);
		}
		break;
	case FD_ACCEPT:
		if (GetLayerState()==listening)
		{
			if (!nErrorCode)
				SetLayerState(connected);
			else
				SetLayerState(aborted);
			OnAccept(nErrorCode);
		}
		break;
	case FD_CLOSE:
		if (GetLayerState()==connected)
		{
			if (nErrorCode)
				SetLayerState(aborted);
			else
				SetLayerState(closed);
			OnClose(nErrorCode);
		}
		break;
	}
}
示例#5
0
BOOL CAsyncSocketExLayer::CreateNext(UINT nSocketPort, int nSocketType, long lEvent, LPCTSTR lpszSocketAddress, int nFamily /*=AF_INET*/)
{
  DebugAssert(GetLayerState()==notsock);
  BOOL res = FALSE;

  m_nFamily = nFamily;

  if (m_pNextLayer)
    res = m_pNextLayer->Create(nSocketPort, nSocketType, lEvent, lpszSocketAddress, nFamily);
  else if (m_nFamily == AF_UNSPEC)
  {
    m_lEvent = lEvent;
    nb_free(m_lpszSocketAddress);
    if (lpszSocketAddress && *lpszSocketAddress)
    {
      m_lpszSocketAddress = static_cast<TCHAR *>(nb_calloc(_tcslen(lpszSocketAddress) + 1, sizeof(TCHAR)));
      _tcscpy(m_lpszSocketAddress, lpszSocketAddress);
    }
    else
      m_lpszSocketAddress = 0;
    m_nSocketPort = nSocketPort;
    res = TRUE;
  }
  else
  {
    SOCKET hSocket=socket(nFamily, nSocketType, 0);
    if (hSocket == INVALID_SOCKET)
    {
      m_pOwnerSocket->Close();
      return FALSE;
    }
    m_pOwnerSocket->m_SocketData.hSocket=hSocket;
    m_pOwnerSocket->AttachHandle(hSocket);
    if (!m_pOwnerSocket->AsyncSelect(lEvent))
    {
      m_pOwnerSocket->Close();
      return FALSE;
    }
    if (m_pOwnerSocket->m_pFirstLayer)
    {
      if (WSAAsyncSelect(m_pOwnerSocket->m_SocketData.hSocket, m_pOwnerSocket->GetHelperWindowHandle(), m_pOwnerSocket->m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE) )
      {
        m_pOwnerSocket->Close();
        return FALSE;
      }
    }
    if (!m_pOwnerSocket->Bind(nSocketPort, lpszSocketAddress))
    {
      m_pOwnerSocket->Close();
      return FALSE;
    }
    res = TRUE;
  }
  if (res)
    SetLayerState(unconnected);
  return res;
}
示例#6
0
void CAsyncSocketExLayer::Init(CAsyncSocketExLayer *pPrevLayer, CAsyncSocketEx *pOwnerSocket)
{
	ASSERT(pOwnerSocket);
	m_pPrevLayer=pPrevLayer;
	m_pOwnerSocket=pOwnerSocket;
	m_pNextLayer=0;
#ifndef NOSOCKETSTATES
	SetLayerState(pOwnerSocket->GetState());
#endif //NOSOCKETSTATES
}
示例#7
0
void CAsyncSocketExLayer::CloseNext()
{
	if (m_addrInfo)
		m_pOwnerSocket->p_freeaddrinfo(m_addrInfo);
	m_nextAddr = 0;
	m_addrInfo = 0;

	m_nPendingEvents = 0;

	SetLayerState(notsock);
	if (m_pNextLayer)
		m_pNextLayer->Close();
}
示例#8
0
BOOL CAsyncSocketExLayer::ListenNext( int nConnectionBacklog)
{
  DebugAssert(GetLayerState()==unconnected);
  BOOL res;
  if (m_pNextLayer)
    res=m_pNextLayer->Listen(nConnectionBacklog);
  else
    res=listen(m_pOwnerSocket->GetSocketHandle(), nConnectionBacklog);
  if (res!=SOCKET_ERROR)
  {
    SetLayerState(listening);
  }
  return res!=SOCKET_ERROR;
}
BOOL CAsyncSocketExLayer::ConnectNext(LPCTSTR lpszHostAddress, UINT nHostPort)
{
	ASSERT(GetLayerState()==unconnected);
	ASSERT(m_pOwnerSocket);
	BOOL res;
	if (m_pNextLayer)
		res = m_pNextLayer->Connect(lpszHostAddress, nHostPort);
	else
	{
		USES_CONVERSION;

		ASSERT(lpszHostAddress != NULL);

		SOCKADDR_IN sockAddr;
//==>optimizer added [shadow2004]
#ifdef OPTIM
		memzero(&sockAddr,sizeof(sockAddr));
#else //OPTIM
		memset(&sockAddr,0,sizeof(sockAddr));
#endif //OPTIM
//<==optimizer added [shadow2004]

		LPCSTR lpszAscii = T2CA(lpszHostAddress);
		sockAddr.sin_family = AF_INET;
		sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);

		if (sockAddr.sin_addr.s_addr == INADDR_NONE)
		{
			LPHOSTENT lphost;
			lphost = gethostbyname(lpszAscii);
			if (lphost != NULL)
				sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
			else
			{
				WSASetLastError(WSAEINVAL);
				res = FALSE;
			}
		}

		sockAddr.sin_port = htons((u_short)nHostPort);

		res = ( SOCKET_ERROR!=connect(m_pOwnerSocket->GetSocketHandle(), (SOCKADDR*)&sockAddr, sizeof(sockAddr)) );
	}

	if (res || WSAGetLastError()==WSAEWOULDBLOCK)
	{
		SetLayerState(connecting);
	}
	return res;
}
示例#10
0
BOOL CAsyncSocketExLayer::ConnectNext( const SOCKADDR* lpSockAddr, int nSockAddrLen )
{
  DebugAssert(GetLayerState()==unconnected);
  DebugAssert(m_pOwnerSocket);
  BOOL res;
  if (m_pNextLayer)
    res=m_pNextLayer->Connect(lpSockAddr, nSockAddrLen);
  else
    res = (SOCKET_ERROR!=connect(m_pOwnerSocket->GetSocketHandle(), lpSockAddr, nSockAddrLen));

  if (res || WSAGetLastError()==WSAEWOULDBLOCK)
    SetLayerState(connecting);
  return res;
}
示例#11
0
BOOL CAsyncSocketExLayer::ListenNext( int nConnectionBacklog)
{
	ASSERT(GetLayerState()==unconnected);
	BOOL res;
	if (m_pNextLayer)
		res=m_pNextLayer->Listen(nConnectionBacklog);
	else
		res=listen(m_pOwnerSocket->GetSocketHandle(), nConnectionBacklog);
	if (res)
	{
		SetLayerState(listening);
	}
	return res;
}
示例#12
0
BOOL CAsyncSocketExLayer::TriggerEvent(long lEvent, int nErrorCode, BOOL bPassThrough /*=FALSE*/ )
{
	ASSERT( m_pOwnerSocket );
	if (m_pOwnerSocket->m_SocketData.hSocket == INVALID_SOCKET)
		return FALSE;

	if (lEvent & FD_CONNECT)
	{
		ASSERT( bPassThrough );
		if (nErrorCode == 0)
			ASSERT( bPassThrough && GetLayerState() == connected);
		else
		{
			SetLayerState(aborted);
			m_nCriticalError = nErrorCode;
		}
	}
	else if (lEvent & FD_CLOSE && nErrorCode == 0)
	{
		SetLayerState(closed);
	}
	else if (lEvent & FD_CLOSE && nErrorCode != 0)
	{
		SetLayerState(aborted);
		m_nCriticalError = nErrorCode;
	}
	ASSERT( m_pOwnerSocket->m_pLocalAsyncSocketExThreadData );
	ASSERT( m_pOwnerSocket->m_pLocalAsyncSocketExThreadData->m_pHelperWindow );
	ASSERT( m_pOwnerSocket->m_SocketData.nSocketIndex != -1);
	t_LayerNotifyMsg *pMsg = new t_LayerNotifyMsg;
	pMsg->lEvent = (lEvent & 0xffff) + (nErrorCode << 16);
	pMsg->pLayer = bPassThrough ? m_pPrevLayer : this;
	BOOL res = PostMessage(m_pOwnerSocket->GetHelperWindowHandle(), WM_SOCKETEX_TRIGGER, (WPARAM)m_pOwnerSocket, (LPARAM)pMsg);
	if (!res)
		delete pMsg;
	return res;
}
示例#13
0
BOOL CAsyncSocketExLayer::CreateNext(UINT nSocketPort, int nSocketType, long lEvent, char* lpszSocketAddress)
{
	ASSERT(GetLayerState()==notsock);
	BOOL res=FALSE;
	if (m_pNextLayer)
		res=m_pNextLayer->Create(nSocketPort, nSocketType, lEvent, lpszSocketAddress);
	else
	{
		SOCKET hSocket=socket(AF_INET, nSocketType, 0);
		if (hSocket==INVALID_SOCKET)
			res=FALSE;

/*
		unsigned long ul = 1;
		ioctlsocket(hSocket, FIONBIO, (unsigned long*)&ul);
		
		int iTimerout = 6000;
		setsockopt( hSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&iTimerout, sizeof( iTimerout));
*/

		m_pOwnerSocket->m_SocketData.hSocket=hSocket;
		m_pOwnerSocket->AttachHandle(hSocket);
		if (!m_pOwnerSocket->AsyncSelect(lEvent))
		{
			m_pOwnerSocket->Close();
			res=FALSE;
		}
		if (m_pOwnerSocket->m_pFirstLayer)
		{
			if (WSAAsyncSelect(m_pOwnerSocket->m_SocketData.hSocket, m_pOwnerSocket->GetHelperWindowHandle(), m_pOwnerSocket->m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE) )
			{
				m_pOwnerSocket->Close();
				res=FALSE;
			}
		}
		if (!m_pOwnerSocket->Bind(nSocketPort, lpszSocketAddress))
		{
			m_pOwnerSocket->Close();
			res=FALSE;
		}
		res=TRUE;
	}
	if (res)
		SetLayerState(unconnected);
	return res;
}
示例#14
0
BOOL CAsyncSocketExLayer::CreateNext(UINT nSocketPort, int nSocketType, long lEvent, LPCSTR lpszSocketAddress)
{
	ASSERT(GetLayerState()==notsock);
	BOOL res=FALSE;
	if (m_pNextLayer)
		res=m_pNextLayer->Create(nSocketPort, nSocketType, lEvent, lpszSocketAddress);
	else
	{
		SOCKET hSocket=socket(AF_INET, nSocketType, 0);
		if (hSocket==INVALID_SOCKET)
			res=FALSE;
		m_pOwnerSocket->m_SocketData.hSocket=hSocket;
		m_pOwnerSocket->AttachHandle(hSocket);
		if (!m_pOwnerSocket->AsyncSelect(lEvent))
		{
			m_pOwnerSocket->Close();
			res=FALSE;
		}
		if (m_pOwnerSocket->m_pFirstLayer)
		{
			if (WSAAsyncSelect(m_pOwnerSocket->m_SocketData.hSocket, m_pOwnerSocket->GetHelperWindowHandle(), m_pOwnerSocket->m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE) )
			{
				m_pOwnerSocket->Close();
				res=FALSE;
			}
		}
		if (!m_pOwnerSocket->Bind(nSocketPort, lpszSocketAddress))
		{
			m_pOwnerSocket->Close();
			res=FALSE;
		}
		res=TRUE;
	}
	if (res)
		SetLayerState(unconnected);
	return res;
}
示例#15
0
bool CAsyncSocketExLayer::TryNextProtocol()
{
  m_pOwnerSocket->DetachHandle(m_pOwnerSocket->m_SocketData.hSocket);
  closesocket(m_pOwnerSocket->m_SocketData.hSocket);
  m_pOwnerSocket->m_SocketData.hSocket = INVALID_SOCKET;

  BOOL ret = FALSE;
  for (; m_nextAddr; m_nextAddr = m_nextAddr->ai_next)
  {
    m_pOwnerSocket->m_SocketData.hSocket = socket(m_nextAddr->ai_family, m_nextAddr->ai_socktype, m_nextAddr->ai_protocol);

    if (m_pOwnerSocket->m_SocketData.hSocket == INVALID_SOCKET)
      continue;

    m_pOwnerSocket->AttachHandle(m_pOwnerSocket->m_SocketData.hSocket);
    if (!m_pOwnerSocket->AsyncSelect(m_lEvent))
    {
      m_pOwnerSocket->DetachHandle(m_pOwnerSocket->m_SocketData.hSocket);
      closesocket(m_pOwnerSocket->m_SocketData.hSocket);
      m_pOwnerSocket->m_SocketData.hSocket = INVALID_SOCKET;
      continue;
    }

    if (m_pOwnerSocket->m_pFirstLayer)
    {
      if (WSAAsyncSelect(m_pOwnerSocket->m_SocketData.hSocket, m_pOwnerSocket->GetHelperWindowHandle(), m_pOwnerSocket->m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
      {
        m_pOwnerSocket->DetachHandle(m_pOwnerSocket->m_SocketData.hSocket);
        closesocket(m_pOwnerSocket->m_SocketData.hSocket);
        m_pOwnerSocket->m_SocketData.hSocket = INVALID_SOCKET;
        continue;
      }
    }

    m_pOwnerSocket->m_SocketData.nFamily = m_nextAddr->ai_family;
    m_nFamily = m_nextAddr->ai_family;
    if (!m_pOwnerSocket->Bind(m_nSocketPort, m_lpszSocketAddress))
    {
      m_pOwnerSocket->DetachHandle(m_pOwnerSocket->m_SocketData.hSocket);
      closesocket(m_pOwnerSocket->m_SocketData.hSocket);
      m_pOwnerSocket->m_SocketData.hSocket = INVALID_SOCKET;
      continue;
    }

    if (connect(m_pOwnerSocket->GetSocketHandle(), m_nextAddr->ai_addr, m_nextAddr->ai_addrlen) == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
    {
      m_pOwnerSocket->DetachHandle(m_pOwnerSocket->m_SocketData.hSocket);
      closesocket(m_pOwnerSocket->m_SocketData.hSocket);
      m_pOwnerSocket->m_SocketData.hSocket = INVALID_SOCKET;
      continue;
    }

    SetLayerState(connecting);

    ret = true;
    break;
  }

  if (m_nextAddr)
    m_nextAddr = m_nextAddr->ai_next;

  if (!m_nextAddr)
  {
    if (p_freeaddrinfo) p_freeaddrinfo(m_addrInfo);
    m_nextAddr = 0;
    m_addrInfo = 0;
  }

  if (m_pOwnerSocket->m_SocketData.hSocket == INVALID_SOCKET || !ret)
    return FALSE;
  else
    return TRUE;
}
示例#16
0
void CAsyncSocketExLayer::CloseNext()
{
	SetLayerState(notsock);
	if (m_pNextLayer)
		m_pNextLayer->Close();
}
示例#17
0
void CAsyncSocketExLayer::CallEvent(int nEvent, int nErrorCode)
{
  if (m_nCriticalError)
  {
    return;
  }
  m_nCriticalError = nErrorCode;
  switch (nEvent)
  {
  case FD_READ:
  case FD_FORCEREAD:
    if (GetLayerState()==connecting && !nErrorCode)
    {
      m_nPendingEvents |= nEvent;
      break;
    }
    else if (GetLayerState()==attached)
      SetLayerState(connected);
    if (nEvent & FD_READ)
      m_nPendingEvents &= ~FD_READ;
    else
      m_nPendingEvents &= ~FD_FORCEREAD;
    if (GetLayerState()==connected || nErrorCode)
    {
      if (nErrorCode)
        SetLayerState(aborted);
      OnReceive(nErrorCode);
    }
    break;
  case FD_WRITE:
    if (GetLayerState()==connecting && !nErrorCode)
    {
      m_nPendingEvents |= nEvent;
      break;
    }
    else if (GetLayerState()==attached)
      SetLayerState(connected);
    m_nPendingEvents &= ~FD_WRITE;
    if (GetLayerState()==connected || nErrorCode)
    {
      if (nErrorCode)
        SetLayerState(aborted);
      OnSend(nErrorCode);
    }
    break;
  case FD_CONNECT:
    if (GetLayerState()==connecting || GetLayerState() == attached)
    {
      if (!nErrorCode)
        SetLayerState(connected);
      else
      {
        if (!m_pNextLayer && m_nextAddr)
          if (TryNextProtocol())
          {
            m_nCriticalError = 0;
            return;
          }
        SetLayerState(aborted);
      }
      m_nPendingEvents &= ~FD_CONNECT;
      OnConnect(nErrorCode);

      if (!nErrorCode)
      {
        if ((m_nPendingEvents & FD_READ) && GetLayerState()==connected)
          OnReceive(0);
        if ((m_nPendingEvents & FD_FORCEREAD) && GetLayerState()==connected)
          OnReceive(0);
        if ((m_nPendingEvents & FD_WRITE) && GetLayerState()==connected)
          OnSend(0);
      }
      m_nPendingEvents = 0;
    }
    break;
  case FD_ACCEPT:
    if (GetLayerState()==listening)
    {
      if (nErrorCode)
        SetLayerState(aborted);
      m_nPendingEvents &= ~FD_ACCEPT;
      OnAccept(nErrorCode);
    }
    break;
  case FD_CLOSE:
    if (GetLayerState()==connected || GetLayerState()==attached)
    {
      if (nErrorCode)
        SetLayerState(aborted);
      else
        SetLayerState(closed);
      m_nPendingEvents &= ~FD_CLOSE;
      OnClose(nErrorCode);
    }
    break;
  }
}
示例#18
0
BOOL CAsyncSocketExLayer::ConnectNext(LPCTSTR lpszHostAddress, UINT nHostPort)
{
  DebugAssert(GetLayerState()==unconnected);
  DebugAssert(m_pOwnerSocket);
  BOOL res = FALSE;
  if (m_pNextLayer)
    res = m_pNextLayer->Connect(lpszHostAddress, nHostPort);
  else if (m_nFamily == AF_INET)
  {
    USES_CONVERSION;

    DebugAssert(lpszHostAddress != NULL);

    SOCKADDR_IN sockAddr;
    memset(&sockAddr,0,sizeof(sockAddr));

    LPSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
    sockAddr.sin_family = AF_INET;
    sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);

    if (sockAddr.sin_addr.s_addr == INADDR_NONE)
    {
      LPHOSTENT lphost;
      lphost = gethostbyname(lpszAscii);
      if (lphost != NULL)
        sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
      else
      {
        WSASetLastError(WSAEINVAL);
        res = FALSE;
      }
    }

    sockAddr.sin_port = htons((u_short)nHostPort);

    res = (SOCKET_ERROR != connect(m_pOwnerSocket->GetSocketHandle(), (SOCKADDR*)&sockAddr, sizeof(sockAddr)) );
  }
  else if (m_nFamily == AF_INET6 || m_nFamily == AF_UNSPEC)
  {
    USES_CONVERSION;

    DebugAssert(lpszHostAddress != NULL);

    addrinfo hints, *res0, *res1;
    SOCKET hSocket;
    int error;
    char port[10];

    if (p_freeaddrinfo) p_freeaddrinfo(m_addrInfo);
    m_nextAddr = 0;
    m_addrInfo = 0;

    memset(&hints, 0, sizeof(addrinfo));
    hints.ai_family = m_nFamily;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = 0;
    _snprintf(port, 9, "%lu", nHostPort);
    error = p_getaddrinfo ? p_getaddrinfo(T2CA(lpszHostAddress), port, &hints, &res0) : 1;
    if (error)
      return FALSE;

    for (res1 = res0; res1; res1 = res1->ai_next)
    {
      if (m_nFamily == AF_UNSPEC)
        hSocket = socket(res1->ai_family, res1->ai_socktype, res1->ai_protocol);
      else
        hSocket = m_pOwnerSocket->GetSocketHandle();

      if (INVALID_SOCKET == hSocket)
      {
        res = FALSE;
        continue;
      }

      if (m_nFamily == AF_UNSPEC)
      {
        m_pOwnerSocket->m_SocketData.hSocket = hSocket;
        m_pOwnerSocket->AttachHandle(hSocket);
        if (!m_pOwnerSocket->AsyncSelect(m_lEvent))
        {
          m_pOwnerSocket->Close();
          res = FALSE;
          continue ;
        }
        if (m_pOwnerSocket->m_pFirstLayer)
        {
          if (WSAAsyncSelect(m_pOwnerSocket->m_SocketData.hSocket, m_pOwnerSocket->GetHelperWindowHandle(), m_pOwnerSocket->m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE) )
          {
            m_pOwnerSocket->Close();
            res = FALSE;
            continue;
          }
        }
        if (m_pOwnerSocket->m_pendingCallbacks.size())
          PostMessage(m_pOwnerSocket->GetHelperWindowHandle(), WM_USER + 2, (WPARAM)m_pOwnerSocket->m_SocketData.nSocketIndex, 0);
      }

      if (m_nFamily == AF_UNSPEC)
      {
        m_pOwnerSocket->m_SocketData.nFamily = m_nFamily = res1->ai_family;
        if (!m_pOwnerSocket->Bind(m_nSocketPort, m_lpszSocketAddress))
        {
          m_pOwnerSocket->m_SocketData.nFamily = m_nFamily = AF_UNSPEC;
          Close();
          continue;
        }
      }

      if (!( res = ( SOCKET_ERROR != connect(m_pOwnerSocket->GetSocketHandle(), res1->ai_addr, res1->ai_addrlen) ) )
        && WSAGetLastError() != WSAEWOULDBLOCK)
      {
        if (hints.ai_family == AF_UNSPEC)
        {
          m_nFamily = AF_UNSPEC;
          Close();
        }
        continue ;
      }

      m_nFamily = res1->ai_family;
      m_pOwnerSocket->m_SocketData.nFamily = res1->ai_family;
      res = TRUE;
      break;
    }

    if (res1)
      res1 = res0->ai_next;

    if (res1)
    {
      m_addrInfo = res0;
      m_nextAddr = res1;
    }
    else
    {
      if (p_freeaddrinfo) p_freeaddrinfo(res0);
    }

    if (INVALID_SOCKET == m_pOwnerSocket->GetSocketHandle())
      res = FALSE ;
  }

  if (res || WSAGetLastError() == WSAEWOULDBLOCK)
  {
    SetLayerState(connecting);
  }
  return res;
}