zclient.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:6k
源码类别:

模拟服务器

开发平台:

C/C++

  1. #include "IClient.h"
  2. #include "KSG_EncodeDecode.h"
  3. #include <errno.h>
  4. #define MAX_TEMP_SIZE 65000
  5. int init_client_socket = 0;
  6. ZPerf g_sendPerf;
  7. ZPerf g_recvPerf;
  8. int IClientThread::action() {
  9. //select进行发送和接收
  10. fd_set read_set, write_set;
  11. struct timeval time_out;
  12. time_out.tv_sec = 0;
  13. time_out.tv_usec = 2;
  14. //char temp_buffer[MAX_TEMP_SIZE]; //64k的临时缓冲区
  15. int length = 0;
  16. while(true) {
  17. if(parent->bStop) 
  18. break;
  19.     FD_ZERO(&read_set);
  20. FD_SET(parent->nSocket, &read_set);
  21. if (select(parent->nSocket + 1, &read_set, NULL, NULL, &time_out) != 0) { //有数据等待读
  22. int bufsize = 0;
  23. char* recv_buffer = parent->buffer->getReceiveBuffer(bufsize);
  24. if (!recv_buffer)
  25. {
  26. usleep(10000);
  27. continue;
  28. }
  29. length = recv(parent->nSocket, recv_buffer, bufsize, 0);
  30. if(length < 0) { //出错了,连接中断
  31. if (errno == EAGAIN || errno == EINTR)
  32. {
  33. usleep(5000);
  34. continue;
  35. }
  36. printf("IClient recv error %dn", errno);
  37. break;
  38. }
  39. else {
  40. // if (length > 0)
  41. // length = length;
  42. parent->buffer->receiveData(length);
  43. }
  44. }
  45. if(parent->bStop) break;
  46. char *send_ptr = parent->buffer->getSendData(length);
  47. if(send_ptr) {
  48. FD_ZERO(&write_set);
  49. FD_SET(parent->nSocket, &write_set);
  50. //printf("send data %dn", length);
  51. if(select(parent->nSocket + 1, NULL, &write_set, NULL, &time_out) != 0) { //有数据等待写
  52. int length1 = send(parent->nSocket, send_ptr, length, 0);
  53. if(length1 < 0) {
  54. if (errno == EAGAIN || errno == EWOULDBLOCK)
  55. continue;
  56. printf("IClient send error %dn", errno);
  57. break;
  58. }
  59. else {
  60. if (length1 != length)
  61. length1 = length1;
  62. parent->buffer->sendData(length1);
  63. }
  64. }
  65. }
  66. #ifndef __linux
  67. Sleep(1);
  68. #else
  69. usleep(1);
  70. #endif
  71. }
  72. if(parent->call_back) parent->call_back(parent->call_back_param, enumServerConnectClose);
  73. parent->buffer->clear();
  74. parent->m_uServerKey = parent->m_uClientKey = 0;
  75. return 0;
  76. }
  77. IClient::IClient(int max_send, int max_receive) {
  78. if(!init_client_socket) {
  79. #ifndef __linux
  80. WSADATA wsa_data;
  81. WSAStartup(MAKEWORD(1, 1), &wsa_data);
  82. #endif
  83. init_client_socket++;
  84. }
  85. buffer = new ZBuffer(max_send, max_receive);
  86. startPerf();
  87. call_back = NULL;
  88. m_uServerKey = m_uClientKey = 0;
  89. bStop = false;
  90. thread = new IClientThread(this);
  91. bConnected = false;
  92. }
  93. IClient::~IClient() {
  94. delete thread;
  95. if(--init_client_socket) {
  96. #ifndef __linux
  97. WSACleanup();
  98. #endif
  99. }
  100. }
  101. int IClient::Startup() {
  102. return 1;
  103. }
  104. int IClient::Cleanup() {
  105. return 1;
  106. }
  107. int IClient::Shutdown() {
  108. bStop = true;
  109. if (bConnected) {
  110. shutdown(nSocket, 2);
  111. closesocket(nSocket);
  112. bConnected = false;
  113. }
  114. return 0;
  115. }
  116. bool IClient::ConnectTo(const char * const &pAddressToConnectServer, unsigned short usPortToConnectServer) {
  117. int nReturn;
  118. if (bConnected)
  119. return false;
  120. nSocket = socket(AF_INET, SOCK_STREAM, 0);
  121. if (nSocket == -1)
  122. return false;
  123.     struct sockaddr_in addrServer;
  124. memset((void*)&addrServer, 0, sizeof(addrServer));
  125. addrServer.sin_family = AF_INET;
  126. addrServer.sin_port = htons(usPortToConnectServer);
  127. addrServer.sin_addr.s_addr = inet_addr(pAddressToConnectServer);
  128. //memset(&addrServer.sin_zero, 0, 8);
  129. nReturn = connect(nSocket,(struct sockaddr *)&addrServer, sizeof(addrServer));
  130. if(nReturn < 0) 
  131. return false;
  132. /* read_index = buffer->getConnection();
  133. if (read_index == -1)
  134. {
  135. return false;
  136. }
  137. write_index = buffer->getConnection();
  138. if (write_index == -1) 
  139. return false;*/
  140. if (call_back) 
  141. call_back(call_back_param, enumServerConnectCreate);
  142. bStop = false;
  143. thread->start();
  144. bConnected = true;
  145. return true;
  146. }
  147. void IClient::RegisterMsgFilter(void * lpParam, CALLBACK_CLIENT_EVENT pfnEventNotify) {
  148. call_back = pfnEventNotify;
  149. call_back_param = lpParam;
  150. }
  151. bool IClient::SendPackToServer( const void * const pData, const unsigned long datalength) {
  152. int count = 0;
  153. while(!m_uClientKey) { //如果还没有密钥,则收第一个包(包含密钥)
  154. #ifndef __linux
  155. Sleep(1);
  156. #else
  157. usleep(1000);
  158. #endif
  159. unsigned int length;
  160. GetPackFromServer(length);
  161. if(++count == 1000)
  162. return false;
  163. }
  164. buffer->packData((const char *)pData, datalength);
  165. int length;
  166. char *data = buffer->completePacket(length);
  167. if(!data) return false;
  168. unsigned& uKey = m_uClientKey;
  169. KSG_EncodeBuf(length, (unsigned char *)data, &uKey);
  170. buffer->sendPacket();
  171. return true;
  172. }
  173. void *IClient::GetPackFromServer(unsigned int &datalength ) {
  174. if(m_uServerKey == 0) { //第一个数据包
  175. ACCOUNT_BEGIN *pAccountBegin = (ACCOUNT_BEGIN * )buffer->getPacket((int &)datalength);
  176. if(pAccountBegin) {
  177. printf("first packet %d %dn", pAccountBegin->ServerKey, pAccountBegin->ClientKey);
  178. if(pAccountBegin->ProtocolType == CIPHER_PROTOCOL_TYPE) {
  179. m_uServerKey = ~(pAccountBegin->ServerKey);
  180. m_uClientKey = ~(pAccountBegin->ClientKey);
  181. }
  182. }
  183. return NULL;
  184. }
  185. else {
  186. char *data = (char*)buffer->getPacket((int &)datalength);
  187. if(data) {
  188. /* printf("-----BEFORE uServerKey = %undatalen = %u, data = ", m_uServerKey, datalength);
  189. for (int i = 0; i < 32; i++)
  190. printf("[%02X] ", ((BYTE *)data)[i]);
  191. printf("n");*/
  192. unsigned& uKey = m_uServerKey;
  193. KSG_DecodeBuf(datalength, (unsigned char *)data, &uKey);
  194. /* printf("-----AFTER uServerKey = %undatalen = %u, data = ", m_uServerKey, datalength);
  195. for (int i = 0; i < 32; i++)
  196. printf("[%02X] ", ((BYTE *)data)[i]);
  197. printf("n");*/
  198. }
  199. return data;
  200. }
  201. }