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

📄 ddksrvsocket.cpp

📁 mod_RSsim
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// DDKSrvSocket.cpp: implementation of the CDDKSrvSocket class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

// # of times a connected server socket will loop for without getting any RX data 
// before it closes and gets ready to accept new connections again.
#define MAX_IDLE_LOOPS   10


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNAMIC( CDDKSrvSocket, CDDKSocket);

// This server socket object will construct a listen socket of accept a pointer to an existing socket.
CDDKSrvSocket::CDDKSrvSocket(unsigned short port,unsigned long IPAddrULONG /*= ADDR_ANY*/, SOCKET * pServerSocket /*=NULL*/) : CDDKSocket()
{
int error;
CHAR errStr[180],debugStr[180];
INT      sockoptEnable = TRUE;   

   m_serverObject = TRUE;
   m_pSocket      = NULL;

   int check1 = 0x1234;
   m_buffer = new char[m_serverBufferSize];
   int check2 = 0x1234;

   // server stuff
   // Create a Thread and then a Server-end socket to listen on later

   // create the listening thread
   m_listenThreadStatus = SOCKET_EX_PENDING;
   m_pWorkerThread      = AfxBeginThread((AFX_THREADPROC)SockAsyncFriend,
                                     this,
                                     THREAD_PRIORITY_TIME_CRITICAL, 0,
                                     CREATE_SUSPENDED
                                    );
   // construct with IP and port or with an existing socket
   if (NULL == pServerSocket)
   {

      // Setup local addressing for listen socket
      m_localSockaddr_in.sin_family           = PF_INET;
      m_localSockaddr_in.sin_addr.S_un.S_addr = INADDR_ANY; //usually default
      if ((m_localSockaddr_in.sin_port = htons((u_short) port)) == 0)
      {
         sprintf(debugStr, "Cannot use port %ld", port);
         OutputDebugString(debugStr);

         // Fail the connection process
         m_socketStatus = SOCKET_UNCONFIGURED;
         return;
      }

      // Map protocol name to protocol number
      if ((m_ppe = getprotobyname("tcp")) == NULL)
      {
         GetSockError(errStr);
         sprintf(debugStr,"Driver cannot connect for listen :%s",errStr);
         OutputDebugString(debugStr);
         // Fail the connection process
         m_socketStatus = SOCKET_UNCONFIGURED;
         return;
      }

      // Allocate a listen socket
      m_socket = socket(PF_INET, SOCK_STREAM, m_ppe->p_proto); 
      // If we could not allocate a socket, we must fail the connection process
      if (INVALID_SOCKET == m_socket)  // recommended NT error check
      {
         GetSockError(errStr);
         sprintf(debugStr, "Cannot create Listen socket :%s",errStr);
         OutputDebugString(debugStr);
          // Fail the connection process
         m_socketStatus = SOCKET_UNCONFIGURED;
         return;
      }
      // now to bind socket to local address+port
      if (0 != bind(m_socket, (sockaddr *)&(m_localSockaddr_in), sizeof(m_localSockaddr_in) ) )
      {
         GetSockError(errStr);
         sprintf(debugStr, "Cannot Bind to Listen socket :%s",errStr);
         OutputDebugString(debugStr);
         // Fail the connection process
         m_socketStatus = SOCKET_UNCONFIGURED;
         return;
      }
      // Set the socket to not delay any sends 
      error = setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, (CHAR FAR * ) &m_sockoptEnable, sizeof (INT));
      // If we could not set the socket parameters, we must fail the connection process
      if (error == (LONG) SOCKET_ERROR)
      {
         int lastError = WSAGetLastError();
         sprintf(debugStr, "Cannot setsockopt error (%ld)", lastError);
         OutputDebugString(debugStr);
         // Fail the connection process
         m_socketStatus = SOCKET_UNCONFIGURED;
         return;
      }
      m_pSocket = &m_socket;
      m_socketStatus = SOCKET_INITIALISED;
   }
   else
   {
      // use a socket provided to us.
      // do this when many threads listen and accept connections on the same socket.
      m_pSocket = pServerSocket;
   }
   m_socketStatus = SOCKET_INITIALISED;

   strcpy(debugStr, "Socket created OK.");
   
   SockDataMessage(debugStr);

   m_listenThreadStatus = SOCKET_EX_RUNNING;
}

CDDKSrvSocket::~CDDKSrvSocket()
{
   // get the thread to die off
   //delete(m_buffer);
   //OutputDebugString("In Server socket destructor\n");
   m_listenThreadStatus = SOCKET_EX_TERMINATE;
   
   // abort any listen in progress, this only executes on 1st comms thread's socket, since it created it
   if (INVALID_SOCKET != m_socket)
   {
      closesocket(m_socket);
      m_socket = INVALID_SOCKET;
   }
   // wait for thread to die off
   CSingleLock lk(&m_threadDeadEvent);
   lk.Lock(5000); // wait max 5 seconds

   if (NULL != AcceptedAsyncSocket)
   {
      closesocket(AcceptedAsyncSocket); //kill accepted instance immediately
      accepted = FALSE;
      OutputDebugString("Server socket closing normally.\n");
      SockStateChanged(SOCKETCURRENTLY_CLOSING);
   }
}

#ifdef _DEBUG
VOID CDDKSrvSocket::Dump(CDumpContext& dc) const
{
   // call the base class first
   CDDKSocket::Dump(dc);

   // dump our object to the debuggers output
   // all important members can be dumped at this stage.
   dc << "Server socket: " << "\n";
} // Dump
#endif // _DEBUG


// ------------------------------ SockSockAsyncFriend ------------------------------
UINT SockAsyncFriend(LPVOID pParam)
{
CHAR     debugStr2[MAX_DEBUG_STR_LEN];
CHAR     debugStr[MAX_DEBUG_STR_LEN];
CDDKSrvSocket* DDKSockPtr;

   Sleep(500);
   // OK now since everyone will be asking me what is this sleep doing here. So I am
   // going to tell U. We are being naughty, this thread actually starts executing 
   // while the parent class is constructing, consequently all calls to virtual functions
   // are made before the parent has initialized completely (constructor body has not yet run)
   // and U ned up using un-initialized variables EEK.

   DDKSockPtr = (CDDKSrvSocket*)pParam;
   try 
   { 
		
      // call the function the thread will run in
      if (DDKSockPtr->IsKindOf(RUNTIME_CLASS( CDDKSrvSocket)))
      {
      CString msgStartup;
         // wait untill the Application is ready for us
         CSingleLock lk(&DDKSockPtr->m_threadStartupEvent);
         lk.Lock(5000); // wait max 5 seconds
         msgStartup.Format("Socket %d listen thread ID=%d running", 
                          DDKSockPtr->m_socket, 
                          GetCurrentThreadId());
         DDKSockPtr->SockDataMessage(msgStartup);
         DDKSockPtr->SockStateChanged(SOCKETCURRENTLY_VOID);
               
         DDKSockPtr->Poll(debugStr);
      }
      else
      {
         sprintf(debugStr2, "CDDKSrvSocket SockAsyncFriend pointer corruption!!!!\n");
         OutputDebugString(debugStr2);
      }
   }
   catch (...) 
   {
      OutputDebugString( "Catch\n" );
      sprintf(debugStr2, "CDDKSrvSocket SockAsyncFriend Exception !!!!\n");
      OutputDebugString(debugStr2);
   }
   try
   {
      DDKSockPtr->m_listenThreadStatus = SOCKET_EX_TERMINATED;
      {
      CString d;
         d.Format("[Thread %4d Terminating.]\n", GetCurrentThreadId());
         OutputDebugString(d);
      }
      DDKSockPtr->m_threadDeadEvent.SetEvent();// CEvent
   }
   catch (...)
   {
      CString msg;
         msg.Format("INTERNAL APPLICATION ERROR FILE %s LINE: %d\n%s\n%s", 
            __FILE__, __LINE__, __MY_APPVERSION__, __DATE__);
      OutputDebugString(msg);
   }
   //AfxEndThread(0);

   return(0);
} // SockAsyncFriend


⌨️ 快捷键说明

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