CListenSocket.cpp
上传用户:hhs829
上传日期:2022-06-17
资源大小:586k
文件大小:4k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. // 
  2. // CListenSocket.cpp
  3. // 
  4. #include "stdafx.h"
  5. #include "CListenSocket.h"
  6. #include "..MediaServerMediaServerDlg.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. //////////////////////////////////////////////////////////////////////////////
  13. CListenSocket::CListenSocket()
  14. {
  15. m_hSocket     = NULL;
  16. m_bListening  = false;
  17. m_nLimitCount = 1;
  18. // Initialize thread event
  19. m_hThrdFinish = ::CreateEvent(NULL,    // pointer to security attributes 
  20.      TRUE,      // flag for manual-reset event 
  21. FALSE,     // flag for initial state 
  22. NULL);     // pointer to event-object name
  23. }
  24. CListenSocket::~CListenSocket()
  25. {
  26. // Stop listening first!
  27. if (m_bListening)
  28. StopListen();
  29. // Close the listen socket
  30. if (m_hSocket)
  31. {
  32. closesocket(m_hSocket);
  33. m_hSocket = NULL;
  34. }
  35. // Release the client sockets
  36. SOCKET  pSock;
  37. POSITION pos = m_ClientList.GetHeadPosition();
  38. while (pos)
  39. {
  40. pSock = (SOCKET) m_ClientList.GetNext(pos);
  41. closesocket(pSock);
  42. }
  43. m_ClientList.RemoveAll();
  44. // Release the thread event
  45. if (m_hThrdFinish)
  46. {
  47. CloseHandle(m_hThrdFinish);
  48. m_hThrdFinish = NULL;
  49. }
  50. }
  51. // Create a socket and place it in listening state
  52. bool CListenSocket::Create(int inPort)
  53. {
  54. // Already start listening...
  55. if (m_hSocket)
  56. return true;
  57. // Create a TCP socket
  58. m_hSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  59. if (m_hSocket == INVALID_SOCKET)
  60. {
  61. m_hSocket = NULL;
  62. return false;
  63. }
  64. // Settings on socket
  65. BOOL  sopt = TRUE;
  66. setsockopt(m_hSocket, IPPROTO_TCP, TCP_NODELAY, (char *)&sopt, sizeof(BOOL));
  67. setsockopt(m_hSocket, SOL_SOCKET, SO_DONTLINGER, (char *)&sopt, sizeof(BOOL));
  68. // Bind socket and listen
  69. struct in_addr bindAddr;
  70. bindAddr.S_un.S_addr = INADDR_ANY;
  71. SOCKADDR_IN   saddr;
  72. memset(&saddr, 0, sizeof(SOCKADDR_IN));
  73. saddr.sin_addr   = bindAddr;
  74. saddr.sin_family = AF_INET;
  75. saddr.sin_port   = htons((WORD)inPort);
  76. if (bind(m_hSocket, (SOCKADDR *)&saddr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) 
  77. {
  78. closesocket(m_hSocket);
  79. m_hSocket = NULL;
  80. return false;
  81. }
  82. if (listen(m_hSocket, SOMAXCONN) !=0) 
  83. {
  84. closesocket(m_hSocket);
  85. m_hSocket = NULL;
  86. return false;
  87. }
  88. return true;
  89. }
  90. // Start up an independent thread to listen socket-connection blockingly
  91. bool CListenSocket::StartListen(void)
  92. {
  93. if (m_hSocket)
  94. {
  95. if (m_bListening)
  96. return true;
  97. // Start a thread
  98. m_bListening = true;
  99. ResetEvent(m_hThrdFinish);
  100. // Make socket blocking
  101. u_long   nonBlock = FALSE;
  102. ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
  103. AfxBeginThread((AFX_THREADPROC)CListenSocket::ListeningThrd, this);
  104. return true;
  105. }
  106. return false;
  107. }
  108. void CListenSocket::StopListen(void)
  109. {
  110. if (m_hSocket && m_bListening)
  111. {
  112. m_bListening = false;
  113. // Change socket from blocking to nonblocking to terminate listening thread
  114. // u_long   nonBlock = TRUE;
  115. // ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
  116. // WaitForSingleObject(m_hThrdFinish, 2000);
  117. // Close the socket
  118. closesocket(m_hSocket);
  119. m_hSocket    = NULL;
  120. }
  121. }
  122. // Accept socket connection
  123. bool CListenSocket::Accept(void)
  124. {
  125. if (m_hSocket)
  126. {
  127. SOCKADDR_IN  saddr;
  128. int len = sizeof(SOCKADDR_IN);
  129. SOCKET accs = accept(m_hSocket, (SOCKADDR *)&saddr, &len);
  130. if (accs == INVALID_SOCKET)
  131. return false;
  132. // Connection limited checking...
  133. if (m_ClientList.GetCount() >= m_nLimitCount)
  134. {
  135. closesocket(accs);
  136. return true;
  137. }
  138. // Settings on the new created socket
  139. BOOL   sopt = TRUE;
  140. setsockopt(accs, IPPROTO_TCP, TCP_NODELAY, (char *)&sopt, sizeof(BOOL));
  141. setsockopt(accs, SOL_SOCKET, SO_DONTLINGER, (char *)&sopt, sizeof(BOOL));
  142. m_ClientList.AddTail(accs);
  143. // Send out a message
  144. ::SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_NEW_SOCKET, 0, 0);
  145. return true;
  146. }
  147. return false;
  148. }
  149. // Socket listening thread, blockingly...
  150. UINT CListenSocket::ListeningThrd(void *pParam)
  151. {
  152. CListenSocket * pListen = (CListenSocket *) pParam;
  153. if (pListen == NULL)
  154. return 0;
  155. while (pListen->m_bListening)
  156. {
  157. // If accept failure, exit
  158. if (!pListen->Accept())
  159. break;
  160. }
  161. SetEvent(pListen->m_hThrdFinish);
  162. return 1;
  163. }
  164. // Connection limited feature
  165. void CListenSocket::SetLimitConnection(int inMax)
  166. {
  167. m_nLimitCount = inMax;
  168. }
  169. int CListenSocket::GetLimitConnection(void)
  170. {
  171. return m_nLimitCount;
  172. }