⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zfxws.cpp

📁 This is a book introduce some tech about Game Engine 3D
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      return ZFX_FAIL;
      }

   // initialize all client slots as invalid
   for (int i=0; i<256; i++) {
      m_Clients[i].skToClient = INVALID_SOCKET;
      m_Clients[i].nID = 0;
      }

   return ZFX_OK;
   } // CreateServer
/*----------------------------------------------------------------*/


/**
 * Send a data package from the server to all connected clients.
 * We need to loop through all active connections and send it.
 */
HRESULT ZFXWS::SendToClients(const ZFXPACKAGE *pPkg) {
   HRESULT hr=ZFX_OK;
   int     nBytes=0;
   int     nSize=g_PkgSize+pPkg->nLength;

   // security checks
   if (m_Mode != NMD_SERVER) return ZFX_FAIL;
   if (nSize > m_nMaxSize) return ZFX_OUTOFMEMORY;

   // serialize data in order to send from one mem segment
   memcpy(m_Buffer, pPkg, g_PkgSize);
   memcpy(m_Buffer+g_PkgSize, pPkg->pData, pPkg->nLength);

   // now go send it actually
   for (UINT i=0; i<m_ClCount; i++) {
      if (m_Clients[i].skToClient != INVALID_SOCKET) {
         nBytes = m_pSockObj->Send(m_Buffer, nSize, m_Clients[i].skToClient);
         // if failed report but go on with next clients
         if ( (nBytes==SOCKET_ERROR) || (nBytes<nSize) )
            hr = ZFX_FAIL;
         }
      }
   return hr;
   } // SendToClients
/*----------------------------------------------------------------*/


/**
 * Send a data package from the server to the given client. We
 * need to loop through all active connections to find that one.
 */
HRESULT ZFXWS::SendToClient(const ZFXPACKAGE *pPkg, UINT nCID) {
   HRESULT hr=ZFX_OK;
   int     nBytes=0;
   int     nSize=g_PkgSize+pPkg->nLength;

   // security checks
   if (m_Mode != NMD_SERVER) return ZFX_FAIL;
   if (nSize > m_nMaxSize) return ZFX_OUTOFMEMORY;

   // serialize data in order to send from one mem segment
   memcpy(m_Buffer, pPkg, g_PkgSize);
   memcpy(m_Buffer+g_PkgSize, pPkg->pData, pPkg->nLength);

   // now go send it actually
   for (UINT i=0; i<m_ClCount; i++) {
      if ( (m_Clients[i].skToClient != INVALID_SOCKET) &&
           (m_Clients[i].nID == nCID) ) {
         nBytes = m_pSockObj->Send(m_Buffer, nSize, m_Clients[i].skToClient);
         // if failed report but go on with next clients
         if ( (nBytes==SOCKET_ERROR) || (nBytes<nSize) )
            hr = ZFX_FAIL;
         }
      }
   return hr;
   } // SendToClient
/*----------------------------------------------------------------*/


/**
 * A client just sends the package over its socket that is
 * connected to the one and only server. No problems here.
 */
HRESULT ZFXWS::SendToServer(const ZFXPACKAGE *pPkg) {
   int nBytes=0;
   int nSize=g_PkgSize+pPkg->nLength;

   // security checks
   if (nSize > m_nMaxSize) return ZFX_OUTOFMEMORY;
   
   // serialize data in order to send from one mem segment
   memcpy(m_Buffer, pPkg, g_PkgSize);
   memcpy(m_Buffer+g_PkgSize, pPkg->pData, pPkg->nLength);

   // if pkg was sent by server then 
   // feed it directly into its own queue
   if (m_Mode == NMD_SERVER) {
      m_pSockObj->FeedByHand( (ZFXPACKAGE*)m_Buffer );
      return ZFX_OK;
      }

   // now go send it actually
   nBytes = m_pSockObj->Send(m_Buffer, nSize);
   if ( (nBytes==SOCKET_ERROR) || (nBytes<nSize) ) {
      Log("error: SendToServer() failed");
      return ZFX_FAIL;
      }

   return ZFX_OK;
   } // SendToServer
/*----------------------------------------------------------------*/


/**
 * Application must call this if a WM_ is coming from network.
 */
HRESULT ZFXWS::MsgProc(WPARAM wp, LPARAM lp) {
   WORD  wEvent, wError;
   
   // get data
   wError = HIWORD(lp);
   wEvent = LOWORD(lp);
   
   // which event
   switch (wEvent) {
      // confirmation after successful connection
      case FD_CONNECT: break;
         
      // client wants to be accepted
      case FD_ACCEPT:  { return OnAccept(); } break;
         
      // we are receiving something
      case FD_READ:    { return OnReceive(wp); } break;
         
      // a client wants to go offline
      case FD_CLOSE:   { return OnDisconnect(wp); } break;
         
      // we sent something?
      case FD_WRITE:   break;
         
      }
   return ZFX_OK;
   } // MsgProc
/*----------------------------------------------------------------*/


/**
 * There is someone is the queue of our server waiting to be accepted
 * so do him the favor.
 */
HRESULT ZFXWS::OnAccept(void) {
   int nSize=0, nBytes=0, i=m_ClCount;

   // maximum of 255 clients at all
   if (m_ClCount >= 255) return ZFX_OUTOFMEMORY;

   // application defined maximum number
   if ( (m_ClMax > 0) &&
        (m_ClCount >= m_ClMax) ) 
      return ZFX_OUTOFMEMORY;

   if (FAILED(m_pSockObj->Accept( &(m_Clients[i].skToClient) )))
      return ZFX_FAIL;

   // SEND ITS ID TO THE NEW CLIENT:
   ZFXPACKAGE *pPkg = (ZFXPACKAGE*)m_Buffer;
   pPkg->pData = &m_Buffer[g_PkgSize];
   pPkg->nLength = sizeof(UINT);
   pPkg->nType   = 0;   // ID Msg
   pPkg->nSender = 0;   // Server
   memcpy(pPkg->pData, &m_ClID, sizeof(UINT));

   // add counters
   m_Clients[i].nID = m_ClID;
   m_ClCount++;
   m_ClID++;

   nSize = g_PkgSize + pPkg->nLength;
   nBytes = m_pSockObj->Send(m_Buffer, nSize, m_Clients[i].skToClient);
   if ( (nBytes==SOCKET_ERROR) || (nBytes<nSize) )
      return ZFX_FAIL;

   // INFORM ALL CLIENTS AND THE SERVER ABOUT THE NEW KID IN TOWN
   pPkg->nType = 1;
   SendToClients(pPkg);

   // feed msg into server msg-queue
   m_pSockObj->FeedByHand(pPkg);
   return ZFX_OK;
   } // OnAccept
/*----------------------------------------------------------------*/


/**
 * The giving socket has data to be received in its queue. Just do it!
 */
HRESULT ZFXWS::OnReceive(SOCKET skReceiving) {
   if (m_bRunning) {
      return m_pSockObj->Receive(skReceiving);
      }
   else {
      Log("error: m_bRunning=0 in ZFXWS::OnReceive");
      return ZFX_FAIL;
      }
   } // OnReceive
/*----------------------------------------------------------------*/


/**
 * Close the given socket if he wants to disconnect.
 */
HRESULT ZFXWS::OnDisconnect(SOCKET skDisconnecting) {
   UCHAR      i=0;

   if (skDisconnecting==INVALID_SOCKET) 
      return ZFX_FAIL;

   if (m_Mode==NMD_SERVER) {

      // delete from the list of active clients
      for (i=0; i<m_ClCount; i++) {
         if (m_Clients[i].skToClient == skDisconnecting)
            break;
         }
     
      if (i>=m_ClCount) {
         Log("error: not listed client wants to be disconnected");
         return ZFX_FAIL;
         }
      
      // shutdown and close socket
      if ( shutdown(m_Clients[i].skToClient,0x02)==SOCKET_ERROR )
         m_pSockObj->LogLastWSAError("shutdown() in ZFXWS::OnDisconnect");
      if ( closesocket(m_Clients[i].skToClient)==SOCKET_ERROR )
         m_pSockObj->LogLastWSAError("closesocket() in ZFXWS::OnDisconnect");
      m_Clients[i].skToClient = INVALID_SOCKET;
      
      // inform clients and the server about disconnect
      ZFXPACKAGE *pPkg = (ZFXPACKAGE*)m_Buffer;
      pPkg->pData   = &m_Buffer[g_PkgSize];
      pPkg->nLength = sizeof(UINT);
      pPkg->nType   = 2;   // ID Msg disconnecting
      pPkg->nSender = 0;   // Server
      memcpy(pPkg->pData, &m_Clients[i].nID, sizeof(UINT));
      SendToClients(pPkg);
      
      // feed msg into server msg-queue
      m_pSockObj->FeedByHand(pPkg);

      // copy last struct to deleted field, adjust counter
      memcpy(&m_Clients[i], &m_Clients[m_ClCount-1], sizeof(ZFXCLIENT));
      m_ClCount--;
      }
   else {
      if ( shutdown(m_pSockObj->GetSocket(),0x02)==SOCKET_ERROR )
         m_pSockObj->LogLastWSAError("shutdown() in ZFXWS::OnDisconnect");
      if ( closesocket(m_pSockObj->GetSocket())==SOCKET_ERROR )
         m_pSockObj->LogLastWSAError("closesocket() in ZFXWS::OnDisconnect");
      }

   Log("one client disconnected");
   return ZFX_OK;
   } // OnDisconnect
/*----------------------------------------------------------------*/


/**
 * write outputstring to attribut outputstream if exists
 * -> IN: bool - flush immediately
 *        char - format string to output
 *        ...  - output values
 */
void ZFXWS::Log(char *chString, ...) {

   char ch[256];
   char *pArgs;
   
   pArgs = (char*) &chString + sizeof(chString);
   vsprintf(ch, chString, pArgs);
   fprintf(m_pLog, "[ZFXWSDevice]: ");
   fprintf(m_pLog, ch);
   fprintf(m_pLog, "\n");
   
   if (g_bLF)
      fflush(m_pLog);
   } // Log
/*----------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -