12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052 |
- /*CAsyncSocketEx by Tim Kosse ([email protected])
- Version 1.1 (2002-11-01)
- --------------------------------------------------------
- Introduction:
- -------------
- CAsyncSocketEx is a replacement for the MFC class CAsyncSocket.
- This class was written because CAsyncSocket is not the fastest WinSock
- wrapper and it's very hard to add new functionality to CAsyncSocket
- derived classes. This class offers the same functionality as CAsyncSocket.
- Also, CAsyncSocketEx offers some enhancements which were not possible with
- CAsyncSocket without some tricks.
- How do I use it?
- ----------------
- Basically exactly like CAsyncSocket.
- To use CAsyncSocketEx, just replace all occurrences of CAsyncSocket in your
- code with CAsyncSocketEx, if you did not enhance CAsyncSocket yourself in
- any way, you won't have to change anything else in your code.
- Why is CAsyncSocketEx faster?
- -----------------------------
- CAsyncSocketEx is slightly faster when dispatching notification event messages.
- First have a look at the way CAsyncSocket works. For each thread that uses
- CAsyncSocket, a window is created. CAsyncSocket calls WSAAsyncSelect with
- the handle of that window. Until here, CAsyncSocketEx works the same way.
- But CAsyncSocket uses only one window message (WM_SOCKET_NOTIFY) for all
- sockets within one thread. When the window recieve WM_SOCKET_NOTIFY, wParam
- contains the socket handle and the window looks up an CAsyncSocket instance
- using a map. CAsyncSocketEx works differently. It's helper window uses a
- wide range of different window messages (WM_USER through 0xBFFF) and passes
- a different message to WSAAsyncSelect for each socket. When a message in
- the specified range is received, CAsyncSocketEx looks up the pointer to a
- CAsyncSocketEx instance in an Array using the index of message - WM_USER.
- As you can see, CAsyncSocketEx uses the helper window in a more efficient
- way, as it don't have to use the slow maps to lookup it's own instance.
- Still, speed increase is not very much, but it may be noticeable when using
- a lot of sockets at the same time.
- Please note that the changes do not affect the raw data throughput rate,
- CAsyncSocketEx only dispatches the notification messages faster.
- What else does CAsyncSocketEx offer?
- ------------------------------------
- CAsyncSocketEx offers a flexible layer system. One example is the proxy layer.
- Just create an instance of the proxy layer, configure it and add it to the layer
- chain of your CAsyncSocketEx instance. After that, you can connect through
- proxies.
- Benefit: You don't have to change much to use the layer system.
- Another layer that is currently in development is the SSL layer to establish
- SSL encrypted connections.
- License
- -------
- 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"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #ifdef DEBUG_NEW
- #define new DEBUG_NEW
- #endif
- #endif
- #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)
- {
- ASSERT(pLayer);
- ASSERT(pOwnerSocket);
- if (m_pNextLayer)
- {
- return m_pNextLayer->AddLayer(pLayer, pOwnerSocket);
- }
- else
- {
- ASSERT(m_pOwnerSocket==pOwnerSocket);
- pLayer->Init(this, m_pOwnerSocket);
- m_pNextLayer=pLayer;
- }
- return m_pNextLayer;
- }
- int CAsyncSocketExLayer::Receive(void* lpBuf, int nBufLen, int nFlags /*=0*/)
- {
- int Result = ReceiveNext(lpBuf, nBufLen, nFlags);
- return Result;
- }
- int CAsyncSocketExLayer::Send(const void* lpBuf, int nBufLen, int nFlags /*=0*/)
- {
- int Result = SendNext(lpBuf, nBufLen, nFlags);
- return Result;
- }
- 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*/ )
- {
- ASSERT(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)
- {
- ASSERT(bPassThrough);
- if (!nErrorCode)
- {
- ASSERT(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;
- }
- }
- 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->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)
- {
- ASSERT(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)
- {
- ASSERT(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)
- {
- ASSERT(GetLayerState()==unconnected);
- ASSERT(m_pOwnerSocket);
- BOOL res = FALSE;
- if (m_pNextLayer)
- res = m_pNextLayer->Connect(lpszHostAddress, nHostPort);
- else if (m_nFamily == AF_INET)
- {
- USES_CONVERSION;
- ASSERT(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;
- ASSERT(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 )
- {
- ASSERT(GetLayerState()==unconnected);
- ASSERT(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 connected
- #ifdef _AFX
- BOOL 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;
- }
- }
- #endif //_AFX
- 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
- {
- ASSERT(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 connected
- #ifdef _AFX
- BOOL 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;
- }
- }
- #endif //_AFX
- 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
- {
- ASSERT(m_pOwnerSocket);
- if ( !getsockname(m_pOwnerSocket->GetSocketHandle(), lpSockAddr, lpSockAddrLen) )
- return TRUE;
- else
- return FALSE;
- }
- }
- 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
- }
- int CAsyncSocketExLayer::GetLayerState()
- {
- return m_nLayerState;
- }
- void CAsyncSocketExLayer::SetLayerState(int nLayerState)
- {
- ASSERT(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 socket
- BOOL 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*/)
- {
- ASSERT(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)
- {
- ASSERT(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*/ )
- {
- ASSERT(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;
- VERIFY(rConnectedSocket.InitAsyncSocketExInstance());
- rConnectedSocket.m_SocketData.hSocket=hTemp;
- rConnectedSocket.AttachHandle(hTemp);
- rConnectedSocket.SetFamily(GetFamily());
- #ifndef NOSOCKETSTATES
- rConnectedSocket.SetState(connected);
- #endif //NOSOCKETSTATES
- }
- 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)
- {
- ASSERT(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;
- }
- #ifndef NOLAYERS
- 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;
- }
- }
- #endif //NOLAYERS
- 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::LogSocketMessage(int nMessageType, LPCTSTR pMsgFormat)
- {
- if (m_pPrevLayer)
- m_pPrevLayer->LogSocketMessage(nMessageType, pMsgFormat);
- else
- m_pOwnerSocket->LogSocketMessage(nMessageType, pMsgFormat);
- }
- bool CAsyncSocketExLayer::LoggingSocketMessage(int nMessageType)
- {
- if (m_pPrevLayer)
- return m_pPrevLayer->LoggingSocketMessage(nMessageType);
- else
- return m_pOwnerSocket->LoggingSocketMessage(nMessageType);
- }
|