| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 | /*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 WinSockwrapper and it's very hard to add new functionality to CAsyncSocketderived classes. This class offers the same functionality as CAsyncSocket.Also, CAsyncSocketEx offers some enhancements which were not possible withCAsyncSocket without some tricks.How do I use it?----------------Basically exactly like CAsyncSocket.To use CAsyncSocketEx, just replace all occurrences of CAsyncSocket in yourcode with CAsyncSocketEx, if you did not enhance CAsyncSocket yourself inany 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 usesCAsyncSocket, a window is created. CAsyncSocket calls WSAAsyncSelect withthe handle of that window. Until here, CAsyncSocketEx works the same way.But CAsyncSocket uses only one window message (WM_SOCKET_NOTIFY) for allsockets within one thread. When the window recieve WM_SOCKET_NOTIFY, wParamcontains the socket handle and the window looks up an CAsyncSocket instanceusing a map. CAsyncSocketEx works differently. It's helper window uses awide range of different window messages (WM_USER through 0xBFFF) and passesa different message to WSAAsyncSelect for each socket. When a message inthe specified range is received, CAsyncSocketEx looks up the pointer to aCAsyncSocketEx instance in an Array using the index of message - WM_USER.As you can see, CAsyncSocketEx uses the helper window in a more efficientway, 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 usinga 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 layerchain of your CAsyncSocketEx instance. After that, you can connect throughproxies.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 establishSSL encrypted connections.License-------Feel free to use this class, as long as you don't claim that you wrote itand this copyright notice stays intact in the source files.If you use this class in commercial applications, please send a short messageto [email protected]*///---------------------------------------------------------------------------#ifndef AsyncSocketExLayerH#define AsyncSocketExLayerH//---------------------------------------------------------------------------#include "AsyncSocketEx.h"//---------------------------------------------------------------------------class CAsyncSocketEx;//---------------------------------------------------------------------------class CAsyncSocketExLayer{  friend CAsyncSocketEx;  friend CAsyncSocketExHelperWindow;protected:  // Protected constructor so that CAsyncSocketExLayer can't be instantiated  CAsyncSocketExLayer();  virtual ~CAsyncSocketExLayer();  // Notification event handlers  virtual void OnAccept(int nErrorCode);  virtual void OnClose(int nErrorCode);  virtual void OnConnect(int nErrorCode);  virtual void OnReceive(int nErrorCode);  virtual void OnSend(int nErrorCode);  // Operations  virtual BOOL Accept(CAsyncSocketEx & rConnectedSocket, SOCKADDR * lpSockAddr = NULL, int * lpSockAddrLen = NULL);  virtual void Close();  virtual BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);  virtual BOOL Connect(const SOCKADDR * lpSockAddr, int nSockAddrLen);  virtual BOOL Create(UINT nSocketPort = 0, int nSocketType = SOCK_STREAM,     long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE,     LPCTSTR lpszSocketAddress = NULL, int nFamily = AF_INET);  virtual BOOL GetPeerName(SOCKADDR * lpSockAddr, int * lpSockAddrLen);  virtual BOOL GetSockName(SOCKADDR * lpSockAddr, int * lpSockAddrLen);  virtual BOOL GetPeerName(CString& rPeerAddress, UINT& rPeerPort);  virtual BOOL GetSockName(CString& rPeerAddress, UINT& rPeerPort);  virtual BOOL Listen(int nConnectionBacklog);  virtual int Receive(void * lpBuf, int nBufLen, int nFlags = 0);  virtual int Send(const void * lpBuf, int nBufLen, int nFlags = 0);  virtual BOOL ShutDown(int nHow = sends);  enum { receives = 0, sends = 1, both = 2 };  // Functions that will call next layer  BOOL ShutDownNext(int nHow = sends);  BOOL AcceptNext(CAsyncSocketEx& rConnectedSocket, SOCKADDR * lpSockAddr = NULL, int * lpSockAddrLen = NULL);  void CloseNext();  BOOL ConnectNext(LPCTSTR lpszHostAddress, UINT nHostPort);  BOOL ConnectNext( const SOCKADDR * lpSockAddr, int nSockAddrLen);  BOOL CreateNext(UINT nSocketPort, int nSocketType, long lEvent, LPCTSTR lpszSocketAddress, int nFamily = AF_INET);  BOOL GetPeerNameNext(SOCKADDR * lpSockAddr, int* lpSockAddrLen);  BOOL GetSockNameNext(SOCKADDR * lpSockAddr, int* lpSockAddrLen);  BOOL GetPeerNameNext(CString & rPeerAddress, UINT& rPeerPort);  BOOL GetSockNameNext(CString & rPeerAddress, UINT& rPeerPort);  BOOL ListenNext(int nConnectionBacklog);  int ReceiveNext(void * lpBuf, int nBufLen, int nFlags = 0);  int SendNext(const void * lpBuf, int nBufLen, int nFlags = 0);  CAsyncSocketEx *m_pOwnerSocket;  // Calls OnLayerCallback on owner socket  int DoLayerCallback(int nType, int nParam1, int nParam2, char * str = 0);  int GetLayerState();  BOOL TriggerEvent(long lEvent, int nErrorCode, BOOL bPassThrough = FALSE);  // Gets the socket family  int GetFamily() const;  // Sets the socket family  bool SetFamily(int nFamily);  // Iterate through protocols  bool TryNextProtocol();  void LogSocketMessageRaw(int nMessageType, LPCTSTR pMsg);  bool LoggingSocketMessage(int nMessageType);private:  // Layer state can't be set directly from derived classes  void SetLayerState(int nLayerState);  int m_nLayerState;  int m_nFamily;  int m_lEvent;  LPTSTR m_lpszSocketAddress;  UINT m_nSocketPort;  addrinfo * m_addrInfo, * m_nextAddr;  // Called by helper window, dispatches event notification and updated layer state  void CallEvent(int nEvent, int nErrorCode);  int m_nPendingEvents;  int m_nCriticalError;  void Init(CAsyncSocketExLayer * pPrevLayer, CAsyncSocketEx * pOwnerSocket);  CAsyncSocketExLayer * AddLayer(CAsyncSocketExLayer * pLayer, CAsyncSocketEx * pOwnerSocket);  CAsyncSocketExLayer * m_pNextLayer;  CAsyncSocketExLayer * m_pPrevLayer;  struct t_LayerNotifyMsg  {    SOCKET hSocket;    CAsyncSocketExLayer * pLayer;    long lEvent;  };};//---------------------------------------------------------------------------#endif // AsyncSocketExLayerH
 |