| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982 | // CAsyncSocketEx by Tim Kosse ([email protected])//            Version 1.1 (2002-11-01)//---------------------------------------------------------------------------// Feel free to use this class, as long as you don't claim that you wrote it// and this copyright notice stays intact in the source files.// If you use this class in commercial applications, please send a short message// to [email protected]//---------------------------------------------------------------------------#include "stdafx.h"#include "AsyncSocketExLayer.h"#include "AsyncSocketEx.h"#define WM_SOCKETEX_NOTIFY (WM_USER+3)//////////////////////////////////////////////////////////////////////// Konstruktion/Destruktion//////////////////////////////////////////////////////////////////////CAsyncSocketExLayer::CAsyncSocketExLayer(){  m_pOwnerSocket = NULL;  m_pNextLayer = NULL;  m_pPrevLayer = NULL;  m_nLayerState = notsock;  m_nCriticalError=0;  m_nPendingEvents = 0;  m_nFamily = AF_UNSPEC;  m_lEvent = 0;  m_lpszSocketAddress = 0;  m_nSocketPort = 0;  m_nextAddr = 0;  m_addrInfo = 0;}CAsyncSocketExLayer::~CAsyncSocketExLayer(){  delete [] m_lpszSocketAddress;}CAsyncSocketExLayer *CAsyncSocketExLayer::AddLayer(CAsyncSocketExLayer *pLayer, CAsyncSocketEx *pOwnerSocket){  DebugAssert(pLayer);  DebugAssert(pOwnerSocket);  if (m_pNextLayer)  {    return m_pNextLayer->AddLayer(pLayer, pOwnerSocket);  }  else  {    DebugAssert(m_pOwnerSocket==pOwnerSocket);    pLayer->Init(this, m_pOwnerSocket);    m_pNextLayer=pLayer;  }  return m_pNextLayer;}int CAsyncSocketExLayer::Receive(void* lpBuf, int nBufLen, int nFlags /*=0*/){  return ReceiveNext(lpBuf, nBufLen, nFlags);}int CAsyncSocketExLayer::Send(const void* lpBuf, int nBufLen, int nFlags /*=0*/){  return SendNext(lpBuf, nBufLen, nFlags);}void CAsyncSocketExLayer::OnReceive(int nErrorCode){  if (m_pPrevLayer)  {    m_pPrevLayer->OnReceive(nErrorCode);  }  else  {    if (m_pOwnerSocket->m_lEvent&FD_READ)    {      m_pOwnerSocket->OnReceive(nErrorCode);    }  }}void CAsyncSocketExLayer::OnSend(int nErrorCode){  if (m_pPrevLayer)  {    m_pPrevLayer->OnSend(nErrorCode);  }  else  {    if (m_pOwnerSocket->m_lEvent&FD_WRITE)    {      m_pOwnerSocket->OnSend(nErrorCode);    }  }}void CAsyncSocketExLayer::OnConnect(int nErrorCode){  TriggerEvent(FD_CONNECT, nErrorCode, TRUE);}void CAsyncSocketExLayer::OnAccept(int nErrorCode){  if (m_pPrevLayer)    m_pPrevLayer->OnAccept(nErrorCode);  else    if (m_pOwnerSocket->m_lEvent&FD_ACCEPT)      m_pOwnerSocket->OnAccept(nErrorCode);}void CAsyncSocketExLayer::OnClose(int nErrorCode){  if (m_pPrevLayer)    m_pPrevLayer->OnClose(nErrorCode);  else    if (m_pOwnerSocket->m_lEvent&FD_CLOSE)      m_pOwnerSocket->OnClose(nErrorCode);}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;}void CAsyncSocketExLayer::Close(){  CloseNext();}void CAsyncSocketExLayer::CloseNext(){  if (m_addrInfo)    freeaddrinfo(m_addrInfo);  m_nextAddr = 0;  m_addrInfo = 0;  m_nPendingEvents = 0;  SetLayerState(notsock);  if (m_pNextLayer)    m_pNextLayer->Close();}BOOL CAsyncSocketExLayer::Connect(LPCTSTR lpszHostAddress, UINT nHostPort){  return ConnectNext(lpszHostAddress, nHostPort);}BOOL CAsyncSocketExLayer::Connect( const SOCKADDR* lpSockAddr, int nSockAddrLen ){  return ConnectNext(lpSockAddr, nSockAddrLen);}int CAsyncSocketExLayer::SendNext(const void *lpBuf, int nBufLen, int nFlags /*=0*/){  if (m_nCriticalError)  {    WSASetLastError(m_nCriticalError);    return SOCKET_ERROR;  }  else if (GetLayerState()==notsock)  {    WSASetLastError(WSAENOTSOCK);    return SOCKET_ERROR;  }  else if (GetLayerState()==unconnected || GetLayerState()==connecting || GetLayerState()==listening)  {    WSASetLastError(WSAENOTCONN);    return SOCKET_ERROR;  }  if (!m_pNextLayer)  {    DebugAssert(m_pOwnerSocket);    int sent = send(m_pOwnerSocket->GetSocketHandle(), (LPSTR)lpBuf, nBufLen, nFlags);    return sent;  }  else  {    return m_pNextLayer->Send(lpBuf, nBufLen, nFlags);  }}int CAsyncSocketExLayer::ReceiveNext(void *lpBuf, int nBufLen, int nFlags /*=0*/){  if (m_nCriticalError)  {    WSASetLastError(m_nCriticalError);    return SOCKET_ERROR;  }  else if (GetLayerState()==notsock)  {    WSASetLastError(WSAENOTSOCK);    return SOCKET_ERROR;  }  else if (GetLayerState()==unconnected || GetLayerState()==connecting || GetLayerState()==listening)  {    WSASetLastError(WSAENOTCONN);    return SOCKET_ERROR;  }  if (!m_pNextLayer)  {    DebugAssert(m_pOwnerSocket);    return recv(m_pOwnerSocket->GetSocketHandle(), (LPSTR)lpBuf, nBufLen, nFlags);  }  else  {    return m_pNextLayer->Receive(lpBuf, nBufLen, nFlags);  }}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];    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 = getaddrinfo(T2CA(lpszHostAddress), port, &hints, &res0);    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      freeaddrinfo(res0);    if (INVALID_SOCKET == m_pOwnerSocket->GetSocketHandle())      res = FALSE ;  }  if (res || WSAGetLastError() == WSAEWOULDBLOCK)  {    SetLayerState(connecting);  }  return res;}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;}//Gets the address of the peer socket to which the socket is connectedBOOL CAsyncSocketExLayer::GetPeerName( CString& rPeerAddress, UINT& rPeerPort ){  return GetPeerNameNext(rPeerAddress, rPeerPort);}BOOL CAsyncSocketExLayer::GetPeerNameNext( CString& rPeerAddress, UINT& rPeerPort ){  if (m_pNextLayer)  {    return m_pNextLayer->GetPeerName(rPeerAddress, rPeerPort);  }  else  {    SOCKADDR* sockAddr;    int nSockAddrLen;    if (m_nFamily == AF_INET6)    {      sockAddr = (SOCKADDR*)new SOCKADDR_IN6;      nSockAddrLen = sizeof(SOCKADDR_IN6);    }    else if (m_nFamily == AF_INET)    {      sockAddr = (SOCKADDR*)new SOCKADDR_IN;      nSockAddrLen = sizeof(SOCKADDR_IN);    }    memset(sockAddr, 0, nSockAddrLen);    BOOL bResult = GetPeerName(sockAddr, &nSockAddrLen);    if (bResult)    {      if (m_nFamily == AF_INET6)      {        rPeerPort = ntohs(((SOCKADDR_IN6*)sockAddr)->sin6_port);        LPTSTR buf = Inet6AddrToString(((SOCKADDR_IN6*)sockAddr)->sin6_addr);        rPeerAddress = buf;        delete [] buf;      }      else if (m_nFamily == AF_INET)      {        rPeerPort = ntohs(((SOCKADDR_IN*)sockAddr)->sin_port);        rPeerAddress = inet_ntoa(((SOCKADDR_IN*)sockAddr)->sin_addr);      }      else      {        delete sockAddr;        return FALSE;      }    }    delete sockAddr;    return bResult;  }}BOOL CAsyncSocketExLayer::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen ){  return GetPeerNameNext(lpSockAddr, lpSockAddrLen);}BOOL CAsyncSocketExLayer::GetPeerNameNext( SOCKADDR* lpSockAddr, int* lpSockAddrLen ){  if (m_pNextLayer)  {    return m_pNextLayer->GetPeerName(lpSockAddr, lpSockAddrLen);  }  else  {    DebugAssert(m_pOwnerSocket);    if ( !getpeername(m_pOwnerSocket->GetSocketHandle(), lpSockAddr, lpSockAddrLen) )    {      return TRUE;    }    else    {      return FALSE;    }  }}//Gets the address of the sock socket to which the socket is connectedBOOL CAsyncSocketExLayer::GetSockName( CString& rSockAddress, UINT& rSockPort ){  return GetSockNameNext(rSockAddress, rSockPort);}BOOL CAsyncSocketExLayer::GetSockNameNext( CString& rSockAddress, UINT& rSockPort ){  if (m_pNextLayer)    return m_pNextLayer->GetSockName(rSockAddress, rSockPort);  else  {    SOCKADDR* sockAddr;    int nSockAddrLen;    if (m_nFamily == AF_INET6)    {      sockAddr = (SOCKADDR*)new SOCKADDR_IN6;      nSockAddrLen = sizeof(SOCKADDR_IN6);    }    else if (m_nFamily == AF_INET)    {      sockAddr = (SOCKADDR*)new SOCKADDR_IN;      nSockAddrLen = sizeof(SOCKADDR_IN);    }    memset(sockAddr, 0, nSockAddrLen);    BOOL bResult = GetSockName(sockAddr, &nSockAddrLen);    if (bResult)    {      if (m_nFamily == AF_INET6)      {        rSockPort = ntohs(((SOCKADDR_IN6*)sockAddr)->sin6_port);        LPTSTR buf = Inet6AddrToString(((SOCKADDR_IN6*)sockAddr)->sin6_addr);        rSockAddress = buf;        delete [] buf;      }      else if (m_nFamily == AF_INET)      {        rSockPort = ntohs(((SOCKADDR_IN*)sockAddr)->sin_port);        rSockAddress = inet_ntoa(((SOCKADDR_IN*)sockAddr)->sin_addr);      }      else      {        delete sockAddr;        return FALSE;      }    }    delete sockAddr;    return bResult;  }}BOOL CAsyncSocketExLayer::GetSockName( SOCKADDR* lpSockAddr, int* lpSockAddrLen ){  return GetSockNameNext(lpSockAddr, lpSockAddrLen);}BOOL CAsyncSocketExLayer::GetSockNameNext( SOCKADDR* lpSockAddr, int* lpSockAddrLen ){  if (m_pNextLayer)    return m_pNextLayer->GetSockName(lpSockAddr, lpSockAddrLen);  else  {    DebugAssert(m_pOwnerSocket);    if ( !getsockname(m_pOwnerSocket->GetSocketHandle(), lpSockAddr, lpSockAddrLen) )      return TRUE;    else      return FALSE;  }}void CAsyncSocketExLayer::Init(CAsyncSocketExLayer *pPrevLayer, CAsyncSocketEx *pOwnerSocket){  DebugAssert(pOwnerSocket);  m_pPrevLayer=pPrevLayer;  m_pOwnerSocket=pOwnerSocket;  m_pNextLayer=0;  SetLayerState(pOwnerSocket->GetState());}int CAsyncSocketExLayer::GetLayerState(){  return m_nLayerState;}void CAsyncSocketExLayer::SetLayerState(int nLayerState){  DebugAssert(m_pOwnerSocket);  int nOldLayerState=GetLayerState();  m_nLayerState=nLayerState;  if (nOldLayerState!=nLayerState)    DoLayerCallback(LAYERCALLBACK_STATECHANGE, GetLayerState(), nOldLayerState);}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;  }}//Creates a socketBOOL CAsyncSocketExLayer::Create(UINT nSocketPort, int nSocketType,      long lEvent, LPCTSTR lpszSocketAddress, int nFamily /*=AF_INET*/){  return CreateNext(nSocketPort, nSocketType, lEvent, lpszSocketAddress, nFamily);}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;    delete [] m_lpszSocketAddress;    if (lpszSocketAddress && *lpszSocketAddress)    {      m_lpszSocketAddress = new TCHAR[_tcslen(lpszSocketAddress) + 1];      _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;}int CAsyncSocketExLayer::DoLayerCallback(int nType, int nParam1, int nParam2, char* str /*=0*/){  if (!m_pOwnerSocket)    return 0;  int nError = WSAGetLastError();  t_callbackMsg msg;  msg.pLayer = this;  msg.nType = nType;  msg.nParam1 = nParam1;  msg.nParam2 = nParam2;  msg.str = str;  m_pOwnerSocket->AddCallbackNotification(msg);  WSASetLastError(nError);  return 0;}BOOL CAsyncSocketExLayer::Listen( int nConnectionBacklog){  return ListenNext( nConnectionBacklog);}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::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ ){  return AcceptNext(rConnectedSocket, lpSockAddr, lpSockAddrLen);}BOOL CAsyncSocketExLayer::AcceptNext( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ ){  DebugAssert(GetLayerState()==listening);  BOOL res;  if (m_pNextLayer)    res=m_pNextLayer->Accept(rConnectedSocket, lpSockAddr, lpSockAddrLen);  else  {    SOCKET hTemp = accept(m_pOwnerSocket->m_SocketData.hSocket, lpSockAddr, lpSockAddrLen);    if (hTemp == INVALID_SOCKET)      return FALSE;    DebugCheck(rConnectedSocket.InitAsyncSocketExInstance());    rConnectedSocket.m_SocketData.hSocket=hTemp;    rConnectedSocket.AttachHandle(hTemp);    rConnectedSocket.SetFamily(GetFamily());    rConnectedSocket.SetState(connected);  }  return TRUE;}BOOL CAsyncSocketExLayer::ShutDown(int nHow /*=sends*/){  return ShutDownNext(nHow);}BOOL CAsyncSocketExLayer::ShutDownNext(int nHow /*=sends*/){  if (m_nCriticalError)  {    WSASetLastError(m_nCriticalError);    return FALSE;  }  else if (GetLayerState()==notsock)  {    WSASetLastError(WSAENOTSOCK);    return FALSE;  }  else if (GetLayerState()==unconnected || GetLayerState()==connecting || GetLayerState()==listening)  {    WSASetLastError(WSAENOTCONN);    return FALSE;  }  if (!m_pNextLayer)  {    DebugAssert(m_pOwnerSocket);    return (shutdown(m_pOwnerSocket->GetSocketHandle(), nHow) == 0);  }  else  {    return m_pNextLayer->ShutDown(nHow);  }}int CAsyncSocketExLayer::GetFamily() const{  return m_nFamily;}bool CAsyncSocketExLayer::SetFamily(int nFamily){  if (m_nFamily != AF_UNSPEC)    return false;  m_nFamily = nFamily;  return true;}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)  {    freeaddrinfo(m_addrInfo);    m_nextAddr = 0;    m_addrInfo = 0;  }  if (m_pOwnerSocket->m_SocketData.hSocket == INVALID_SOCKET || !ret)    return FALSE;  else    return TRUE;}void CAsyncSocketExLayer::LogSocketMessageRaw(int nMessageType, LPCTSTR pMsg){  if (m_pPrevLayer)    m_pPrevLayer->LogSocketMessageRaw(nMessageType, pMsg);  else    m_pOwnerSocket->LogSocketMessageRaw(nMessageType, pMsg);}bool CAsyncSocketExLayer::LoggingSocketMessage(int nMessageType){  if (m_pPrevLayer)    return m_pPrevLayer->LoggingSocketMessage(nMessageType);  else    return m_pOwnerSocket->LoggingSocketMessage(nMessageType);}
 |