Socket.cpp
上传用户:guangzhiyw
上传日期:2007-01-09
资源大小:495k
文件大小:6k
源码类别:

ICQ/即时通讯

开发平台:

Visual C++

  1. ////////////////////////////////////////////////////////////////
  2. // FileName: Socket.cpp   //
  3. //   //
  4. // 服务器的底层通讯CServerSocket类   //
  5. //   //
  6. ////////////////////////////////////////////////////////////////
  7. #include "stdafx.h"
  8. #include "common.h"
  9. #include "Socket.h"
  10. #include "data.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CRecvSocket
  18. CRecvSocket::CRecvSocket()
  19. {
  20. strcpy(m_szResponseMsg,ResponseMsg);
  21. m_szrLength=strlen(m_szResponseMsg);
  22. }
  23. CRecvSocket::~CRecvSocket()
  24. {
  25. }
  26. // Do not edit the following lines, which are needed by ClassWizard.
  27. #if 0
  28. BEGIN_MESSAGE_MAP(CRecvSocket, CAsyncSocket)
  29. //{{AFX_MSG_MAP(CRecvSocket)
  30. //}}AFX_MSG_MAP
  31. END_MESSAGE_MAP()
  32. #endif // 0
  33. /////////////////////////////////////////////////////////////////////////////
  34. // CRecvSocket member functions
  35. BOOL CRecvSocket::Create(int nPort)
  36. {
  37. TRACE1("Create Listen Socket : %dn",nPort);
  38. return CAsyncSocket::Create(nPort,SOCK_DGRAM,FD_READ|FD_CLOSE);
  39. }
  40. void CRecvSocket::OnReceive(int nErrorCode) 
  41. {
  42. // TODO: Add your specialized code here and/or call the base class
  43. OutputDebugString("CUdpSocket::OnReceiven");
  44. char buff[DataBufLength];
  45. int nRead;
  46. CString sIP;
  47. UINT nPort;
  48. nRead = ReceiveFrom(buff,DataBufLength, sIP, nPort);
  49. if (nRead != SOCKET_ERROR && nRead != 0 )
  50. {
  51. CData* pData=new CData;
  52. StrNCopy(pData->szBuf,buff,nRead);
  53. pData->num=nRead;
  54. pData->nPort=nPort;
  55. pData->tarIP=inet_addr(sIP);
  56. if(pData->LoadFromBuf())
  57. {
  58. StrNCopy(m_szResponseMsg+m_szrLength,(char*)&pData->This,sizeof(DWORD));
  59. SendTo(m_szResponseMsg,m_szrLength+sizeof(DWORD),nPort,sIP);
  60. AfxBeginThread(ProcessRecvData,(LPVOID)pData);
  61. }
  62. }
  63. CAsyncSocket::OnReceive(nErrorCode);
  64. }
  65. /////////////////////////////////////////////////////////////////////////////
  66. // CSendSocket
  67. CSendSocket::CSendSocket(BYTE*buf):pBuf(buf)
  68. {
  69. strcpy(m_szResponseMsg,ResponseMsg);
  70. m_szrLength=strlen(m_szResponseMsg);
  71. }
  72. CSendSocket::~CSendSocket()
  73. {
  74. }
  75. // Do not edit the following lines, which are needed by ClassWizard.
  76. #if 0
  77. BEGIN_MESSAGE_MAP(CSendSocket, CAsyncSocket)
  78. //{{AFX_MSG_MAP(CSendSocket)
  79. //}}AFX_MSG_MAP
  80. END_MESSAGE_MAP()
  81. #endif // 0
  82. /////////////////////////////////////////////////////////////////////////////
  83. // CSendSocket member functions
  84. BOOL CSendSocket::Create()
  85. {
  86. return CAsyncSocket::Create(0,SOCK_DGRAM,FD_READ);
  87. }
  88. void CSendSocket::OnReceive(int nErrorCode) 
  89. {
  90. // TODO: Add your specialized code here and/or call the base class
  91. char buff[DataBufLength];
  92. int nRead;
  93. CString sIP;
  94. UINT nPort;
  95. nRead = ReceiveFrom(buff,DataBufLength, sIP, nPort);
  96. if (nRead != SOCKET_ERROR && nRead != 0 )
  97. {
  98. // Check if is the response message
  99. if(StrNSame(buff,m_szResponseMsg,nRead-4,m_szrLength))
  100. {
  101. DWORD Index=*((DWORD*)(buff+nRead-4));
  102. if(Index<CheckBufLength)  // find it
  103. {
  104. pBuf[Index]=1;
  105. TRACE1("Recv Res this: %d n",Index);
  106. }
  107. }
  108. }
  109. CAsyncSocket::OnReceive(nErrorCode);
  110. }
  111. //////////////////////////////////////////////////////////////////////
  112. // CServerSocket Class
  113. //////////////////////////////////////////////////////////////////////
  114. //////////////////////////////////////////////////////////////////////
  115. // Construction/Destruction
  116. //////////////////////////////////////////////////////////////////////
  117. CServerSocket::CServerSocket()
  118. {
  119. m_nRecvSocket=0;
  120. m_nSendSocket=0;
  121. memset(m_abBusy,0,sizeof(m_abBusy));
  122. memset(m_arBuf,0,sizeof(m_arBuf));
  123. m_nTotalSend=0;
  124. }
  125. CServerSocket::~CServerSocket()
  126. {
  127. }
  128. BOOL CServerSocket::Create(int SendSockNum,CArray<DWORD,DWORD>&aRecvPort,int TimeOut)
  129. {
  130. m_nSendSocket=SendSockNum;
  131. m_nRecvSocket=aRecvPort.GetSize();
  132. m_nTimeOut=TimeOut;
  133. ASSERT(m_nRecvSocket>=1&&m_nSendSocket>=1);
  134. BOOL CreateSuccess=TRUE;
  135. for(int i=0;i<m_nSendSocket&&CreateSuccess;i++)
  136. {
  137. m_apSendSocket[i]=new CSendSocket(m_arBuf);
  138. CreateSuccess=m_apSendSocket[i]->Create();
  139. }
  140. for(int j=0;j<m_nRecvSocket&&CreateSuccess;j++)
  141. {
  142. m_apRecvSocket[j]=new CRecvSocket();
  143. CreateSuccess=m_apRecvSocket[j]->Create(aRecvPort.GetAt(j));
  144. }
  145. return CreateSuccess;
  146. }
  147. BOOL CServerSocket::SendData(CData *pData,int FailReDoTimes)
  148. {
  149. ASSERT(pData!=NULL);
  150. ASSERT(m_nSendSocket&&m_nRecvSocket);
  151. int times=0,iCurIndex;
  152. BOOL bSendSuccess=FALSE;
  153. m_nTotalSend++;
  154. iCurIndex=m_nTotalSend%CheckBufLength;
  155. m_arBuf[iCurIndex]=0;
  156. pData->This=iCurIndex;
  157. pData->PackToBuf();
  158. CString strIP;
  159. in_addr tIP;
  160. tIP.S_un.S_addr=pData->tarIP;
  161. strIP=inet_ntoa(tIP);
  162. for(int i=0;i<m_nSendSocket&&times<FailReDoTimes&&!bSendSuccess;i++,i%=m_nSendSocket)
  163. if(!m_abBusy[i])
  164. {
  165. m_abBusy[i]=TRUE;
  166. DWORD tBegin=GetTickCount();
  167. m_apSendSocket[i]->SendTo(pData->szBuf,pData->num,pData->nPort,strIP);
  168. m_abBusy[i]=FALSE;
  169. while(!m_arBuf[iCurIndex]&&GetTickCount()-tBegin<m_nTimeOut);
  170. bSendSuccess=m_arBuf[iCurIndex];
  171. TRACE3("Send Data index:%d This:%d iCurI:%dn",pData->index,pData->This,iCurIndex);
  172. times++;
  173. }
  174. return bSendSuccess;
  175. }
  176. void CRecvSocket::OnClose(int nErrorCode) 
  177. {
  178. // TODO: Add your specialized code here and/or call the base class
  179. TRACE0("CRecvSocket :: Onclose n");
  180. CAsyncSocket::OnClose(nErrorCode);
  181. }
  182. void CServerSocket::CloseListenSocket()
  183. {
  184. for(int i=0;i<m_nRecvSocket;i++)
  185. {
  186. m_apRecvSocket[i]->Close();
  187. delete m_apRecvSocket[i];
  188. }
  189. }
  190. void CServerSocket::CloseSendSocket()
  191. {
  192. for(int i=0;i<m_nSendSocket;i++)
  193. {
  194. m_apSendSocket[i]->Close();
  195. delete m_apSendSocket[i];
  196. }
  197. }